在C中使用许多输入参数优化函数

时间:2016-12-01 17:12:38

标签: c performance optimization parameter-passing

我的代码中有一个大循环内的函数,它占用了大部分的cpu时间:

res

其中inline void myfunc(double *v1, ... , double *vN){ ... (general, complex, multiline manipulation of *v1 .. *vN) ... res = *v1; } 是一个全局变量,传递参数的数量N大约为20.我试图通过传递变量指针来优化函数调用:

myfunc(&v1, ..., &vN)

然后当然是colsplit, melt, recast 调用它。我假设在每次调用的第一种情况下,函数必须创建局部v1..vN变量,而在第二种情况下它不需要。 我发现两个版本都有效(呃!)但实际上我对第二种情况没有加速。那是为什么?

2 个答案:

答案 0 :(得分:2)

不是将sizeof(double*)作为参数复制到函数中,而是复制指针。

如果您使用double(每个size_t)架构,则指针为double,与x64完全相同。

不止于此:

  • 现在您需要取消引用传递的参数。
  • 在将它们传递给方法之前,您需要获取指向它们的指针
  • 您在计算本身中丢失了可能的编译器优化 ,这可能比通过的参数更昂贵。

如果此方法包含需要很长时间的操作,那么 优化操作本身 而不是传递参数。

您没有提供足够的信息来帮助您优化函数体本身,但是要知道,对于重载矢量计算,您可能希望使用多线程处理 - 甚至可能在GPU上。

答案 1 :(得分:1)

想想你在做什么:

  • myfunc的第一个版本中,您按值传递 N double参数,使{strong> N 副本{ {1}}。

  • 在第二个版本中,您按值传递 N sizeof(double)个参数,然后访问它们。您正在制作double* N 副本,然后执行指针间接。传递指针/引用也会阻止编译器执行更积极的优化。

简而言之,第二个版本比第一个版本做的工作更多。如果你没有看到任何区别,那么编译器很可能能够优化间接/拷贝。

您可以使用精彩的gcc.godbolt.org网站轻松比较多个编译器上两个版本的生成程序集。