首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对开源软件中使用的某个编程技巧的查询

对开源软件中使用的某个编程技巧的查询
EN

Stack Overflow用户
提问于 2015-07-21 10:07:21
回答 1查看 43关注 0票数 2

在某个库(FFTW:离散傅里叶变换计算)中,我遇到了一个头文件,其中包含以下注释,一些#定义如下。这则评论谈到了一些编程技巧。但我无法理解这个编程技巧到底是什么。谁能解释一下吗?

代码语言:javascript
复制
/* hackery to prevent the compiler from ``optimizing'' induction
   variables in codelet loops.  The problem is that for each K and for
   each expression of the form P[I + STRIDE * K] in a loop, most
   compilers will try to lift an induction variable PK := &P[I + STRIDE * K].
   For large values of K this behavior overflows the
   register set, which is likely worse than doing the index computation
   in the first place.

   If we guess that there are more than
   ESTIMATED_AVAILABLE_INDEX_REGISTERS such pointers, we deliberately confuse
   the compiler by setting STRIDE ^= ZERO, where ZERO is a value guaranteed to
   be 0, but the compiler does not know this.

   16 registers ought to be enough for anybody, or so the amd64 and ARM ISA's
   seem to imply.
*/

#define ESTIMATED_AVAILABLE_INDEX_REGISTERS 16
#define MAKE_VOLATILE_STRIDE(nptr, x)                   \
     (nptr <= ESTIMATED_AVAILABLE_INDEX_REGISTERS ?     \
        0 :                                             \
      ((x) = (x) ^ X(an_INT_guaranteed_to_be_zero)))
#endif /* PRECOMPUTE_ARRAY_INDICES */
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-23 11:25:43

优化:一些编译器没有在循环中每次迭代时重新计算数组的索引,而是预测下一个地址并将它们放入寄存器中,因为索引表达式是可预测的。

问题是:一些索引表达式(如I + STRIDE * K)可能导致大量寄存器的使用,如果这个数目超过寄存器的总数,一些寄存器值将被推入堆栈内存,包括循环可能使用的其他变量。

诀窍:为了迫使编译器不使用这种优化,使用了一个外部整数。添加或异或将此零添加或存储在x中是一个“污染”步幅的无操作操作,因此也就是索引表达式,通过优化分析使其不可预测。即使我们知道它的行为非常零,它也无法推断这个变量的行为。从中派生的文件ifftw.h的相关摘录:

代码语言:javascript
复制
extern const INT X(an_INT_guaranteed_to_be_zero);

#ifdef PRECOMPUTE_ARRAY_INDICES
...
#define MAKE_VOLATILE_STRIDE(nptr, x) (x) = (x) + X(an_INT_guaranteed_to_be_zero)

#else
...
#define ESTIMATED_AVAILABLE_INDEX_REGISTERS 16
#define MAKE_VOLATILE_STRIDE(nptr, x)                   \
     (nptr <= ESTIMATED_AVAILABLE_INDEX_REGISTERS ?     \
        0 :                                             \
      ((x) = (x) ^ X(an_INT_guaranteed_to_be_zero)))
#endif /* PRECOMPUTE_ARRAY_INDICES */

尝试完全避免这种优化,或者允许在索引能够适合猜测可用寄存器数量的条件下进行优化。它允许优化的方式是使用常数为零。

一些词源:宏MAKE_VOLATILE_STRIDE从易失性关键字派生其名称,该关键字指示一个值在不同的访问之间可能会发生变化,即使它似乎没有被修改。此关键字可防止优化编译器对后续的读或写进行优化,从而错误地重用陈旧的值或省略写入。(维基百科)

我不知道为什么可变关键字(而不是XOR‘’ing外部值)是不够的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31536087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档