我想将一个C数组数据复制到另一个C数组,但需要在两个C数组之间进行计算(即,不仅要将相同的内容从一个C数组复制到另一个C数组,还要对数据进行修改):
int aaa;
int src[ARRAY_SIZE];
int dest[ARRAY_SIZE];
//fill src with data
for (aaa = 0; aaa < ARRAY_SIZE; aaa++)
{
dest[aaa] = src[aaa] * 30;
}
这是在大小为520或更高的缓冲区中完成的,因此for循环相当可观。
在编码方面有什么方法可以提高性能吗?
我做了一些关于这个主题的研究,但是我找不到关于这个案例的任何具体内容,只有关于简单的复制缓冲区到缓冲区(例如:here,here和here)。
环境:GCC for ARM使用嵌入式Linux。不过,上面的特定代码是在一个C项目中使用的,该项目在一个专用处理器中运行,用于DSP计算。通用处理器是OMAP L138(L138中包含了数字信号处理器)。
最佳答案
您可以尝试诸如循环展开或duff的设备之类的技术,但是如果您打开编译器优化,它可能会在任何情况下为您这样做,如果它是有利的,而不会使您的代码不可读。
依赖编译器优化的优势在于它是特定于体系结构的;在一个目标上工作的源代码级技术在另一个目标上可能不会很好地工作,但是编译器生成的优化将特定于目标。例如,在C语言中没有办法专门为SIMD指令编写代码,但是编译器可能会生成代码来利用它们,为此,最好保持代码的简单和直接,以便编译器能够发现这个习惯用法。为“手动优化”编写奇怪的代码可能会击败优化器并阻止它完成其工作。
另一种可能对某些目标有利(如果您只为桌面x86目标编码,这可能与此无关),那就是使用移位来避免乘法指令:
如果x * 30
等同于x * 32 - x * 2
,则循环中的表达式可以替换为:
input[aaa] = (output[aaa] << 5) - (output[aaa] << 1) ;
不过,优化器同样可以为您做到这一点;它还可以避免重复计算
output[aaa]
,但如果不是这样,则以下可能是有益的:int i = output[aaa] ;
input[aaa] = (i << 5) - (i << 1) ;
移位技术对于大多数目标上成本更高的除法操作可能更为有利,而且它只适用于常数。
这些技术可能会提高未优化代码的性能,但编译器优化可能会做得更好,原始代码可能比“手动优化”代码优化得更好。
最后,如果这很重要,您必须进行实验并执行计时测试或分析。