我正在学习使用OpenGL和C进行3D渲染,并编写了一个小型数学库用于学习。使用return
语句返回矩阵乘法函数的结果更好,还是通过指针修改输出矩阵更好?
typedef float vec_t;
typedef struct mat4_s {
vec_t m[4][4];
} mat4_t;
void Mat4Mult(mat4_t* out, const mat4_t* in1, const mat4_t* in2) {
out->m[0][0] = /* ... */;
out->m[1][0] = /* ... */;
/* ... */
}
mat4_t Mat4Mult(const mat4_t* in1, const mat4_t* in2) {
mat4_t result;
result.m[0][0] = /* ... */;
result.m[1][0] = /* ... */;
/* ... */
return result;
}
我想知道哪种选择更正确。我认为这两个选项都是正确的,但我更喜欢使用return
语句返回函数的结果。如果我说错了请纠正我,我还没有完全掌握C。
1条答案
按热度按时间yc0p9oo01#
凭直觉回答这些问题是非常困难的,即使你有堆积如山的经验。这就是为什么你应该尝试这两种方法,并分析结果。让我们比较以下简单的4x4矩阵乘法函数:
Clang 15.0 Results
GCC 12.2 Results
结果在GCC和clang之间显著不同。查看程序集,这可能是因为clang内联了
_Ret
版本,但没有对_Dest
版本做同样的操作。GCC内联了这两个函数,使它们的性能基本相同。这并不奇怪,因为这两个函数执行相同的计算。总结
根据基准测试,按值返回至少与写入目标矩阵一样快。它对某些编译器更内联友好,这可能会提高性能。但是,通过对函数进行注解,使其更有可能被内联,也可以获得相同的结果。
值得注意的是,在
Mat4Mul_Ret
中,return out;
无论如何都会就地写入目标,因为大型对象是通过x86_64 ABI中的目标指针传递的:但是,您的函数之间有一个显着的差异:
mat4_t* out
可以别名为in1
和in2
,但本地mat4_t out
不能。* * 考虑将指针标记为restrict
,让编译器有更大的优化自由度。**