【发布时间】:2012-06-04 00:21:32
【问题描述】:
声明
a[i] += a[j] * a[k];
将在一个可能被执行数千到数百万次的循环中执行数千次。索引i、j和k,代表随机访问a中的条目,可以通过语句设置
i = i_index[l];
j = j_index[l];
k = k_index[l];
其中l 是for 循环的索引。整数数组i_index、j_index和k_index在程序开始时设置,可能会偶尔更改。
内存指针数组是另一种选择。例如
*ap1[l] += *ap2[l] * (*ap3[l]);
其中内存指针数组ap1、ap2和ap3被预先设置为指向最初由i_index、j_index和k_index数组标识的位置。它们也可能偶尔更改。
第一种方法看起来比第二种方法更简洁,但它似乎更慢,除非有某种方法可以向编译器提供额外的信息。 XCode 中的 GCC 编译器似乎无法提前发现 i_index、j_index 和 k_index 或 ap1、ap2 和 ap3 大部分时间是不变的。有什么方法可以提醒 gcc 编译器以提高性能?
【问题讨论】:
-
您确定干净的解决方案 较慢吗?
-
首先要尽可能清晰、直接地编写代码。奇怪的是,之后的更改不会使其更快。
-
同时编写更简洁的代码使其更易于理解、可维护且不易出错。为了让事情变得更快,首先进行分析。
-
第二个版本不需要所有这些括号,因为
[]的优先级高于一元*- 所以*ap1[l] += *ap2[l] * *ap3[l];很好。 -
您能否安排代码以使对 a 的访问尽可能线性?这将加快 IMO 的速度。如果没有,请查看一个分析器运行,它会告诉您缓存抖动,然后尝试尽可能减少抖动。