一定要摆脱
pow()
。这在很大程度上取决于你如何使用它进行优化。你是针对非常大的N只做一次并且花费太长时间吗?还是更有可能是在一个紧密循环中多次执行?
如果你正在使用非常大的N(>1000左右),那么有高度优化的数值库可以做到这一点。例如,BLAS具有一个
*nrm2
函数,可以计算欧几里得范数(
dnrm2
、
snrm2
、
cnrm2
、
znrm2
,根据数据类型而定[单精度、双精度、复杂单精度、复杂双精度])。
GotoBLAS可能是某些处理器架构中最快的。
MKL特色是英特尔手工调整的BLAS实现,但它不是免费的。最后,
ATLAS是一个自我调整的库,实现了BLAS。
如果您有一个紧密的循环,N 很小或不是很大,那么您可能需要手动调整一些参数以使其更快。您可以使用编译器标志
-O3
或
-ftree-vectorize
来启用自动向量化。您也可以手动进行矢量化,但学习如何这样做可能会很痛苦。
您可以进行循环展开(即将 N 分成一些块,比如 4,并在 for 循环体内明确编写 4 个连续值的计算公式)。这样可以欺骗编译器使用更多寄存器进行立即计算——而寄存器是您要处理的最快形式的内存。此外,您可能还可以利用预取(使用一个内存访问调用读取一段数据)。
在这种情况下,另一件要做的事是尝试覆盖其中一个输入。也就是说,您可以将输出写入
或中,以此来帮助您计算的< p >位置仍然在缓存中,当您准备好写入时,缓存通常不会将数据写入内存,除非他们绝对必须这样做---原因之一是需要缓存行并且我们需要将上一个踢出。通过写入其中一个输入来使用更少的缓存行。
还有500,000其他要尝试的事情,但我想在这里停止。祝你好运!
*axpy
函数来计算两个向量的差。代码应该类似于*axpy(N, -1, p, 1, q, 1); answer = *nrm2(N, p, 1);
。 - nevsan