编译器和高端处理器管道中的布尔表达式优化

时间:2017-11-10 14:59:40

标签: gcc optimization compilation mathematical-optimization pipeline

我想计算一个布尔表达式。为了便于理解,我们假设表达式为

O =(A& B& C)| (D& E& F)---(eqn.1),

这里A,B,C,D,E和F是随机位。现在,由于我的目标平台是支持64位数据类型的高端intel i7-Haswell处理器,因此我可以使用位切片提高效率。 所以现在,O,A,B,C,D,E和f是64位数据类型,

O_64 =(A_64& B_64& C_64)| (D_64& E_64& F_64)---(eqn.2),&和|是与C语言类似的按位运算符。

现在,我需要表达式来持续执行时间。这意味着,计算公式。 2应该采用处理器中的确切步数,而不管A_64,B_64,C_64,D_64,E_64和F_64中的值。使用运行时中的随机生成器填充值。

现在我的问题是,

  1. 考虑到我使用GCC或GCC-7和-O3,编译器可以在多长时间内优化表达式?例如,如果A_64变为全零(可能以2 ^ { - 64}的概率发生)那么我们不需要计算方程2的第一部分然后O_64变得等于D_64& E_64& F_64。 c编译器是否可以优化这种方式?我们必须记住,值在运行时填充,布尔表达式有大约120个变量。

  2. 处理器是否可以在运行时进行此类优化(列表1)?由于我的布尔表达式非常长,执行将大量流水线化,如果出现这种情况,处理器是否有可能将操作从管道中拉出来?

  3. 如果问题的任何部分不可理解,请告诉我。 感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

  

c编译器是否可以优化这种方式?

允许这样做,但可能不会。一般来说没有任何好处。如果静态地知道表达式的一部分为零,则将使用该表达式。但是在按位计算中插入分支几乎总是适得其反,而且我从未见过编译器将AND序列判断为“足够长,值得插入早期”(当然,您当然可以手动执行此操作)。如果你需要一个硬保证当然我不能给你,如果你想确定你应该总是检查组件。

它可能会做什么(至少对于更长的表达式)是重新关联表达式以获得更多的指令级并行性。因此,这样的代码可能不会只是两个长(但彼此平行)依赖AND的链,而是分成更多的链。那仍然不会让时间取决于价值观。

  

处理器是否有可能在运行时进行这样的优化?

非常假设是的。我所知道的处理器架构没有这样做。这将是一个稍微棘手的机制,作为一般规则,它几乎从来没有帮助。

假设它可以这样工作:当查找AND指令的操作数并且发现它们中的一个(或两个)被重命名为硬连线零寄存器时,重命名器可以立即将目标重命名为也是零(而不是为结果分配新的寄存器),有效地给出AND指令0延迟。标志输出也是已知的,因此甚至不必执行μop。它大致是复制消除和归零成语之间的交叉。

如果输入意外为零而无法检测到,则除非其中一个输入设置为零,否则该机制甚至不会触发。它也不会完全消除冗余AND指令的影响,它们仍然必须通过(大部分)处理器的前端,即使它只是发现它们根本不需要执行