编译器和高端处理器流水线中的布尔表达式优化
Boolean expression optimization in compiler and high end processor pipeline
我想计算一个布尔表达式。为了便于理解,我们假设表达式是
O=(A & B & C) | ( D & E & F)---(eqn. 1),
这里A、B、C、D、E、F是随机比特。现在,由于我的目标平台是支持 64 位数据类型的高端英特尔 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 和 [=40 中的值=].这些值在运行时使用随机生成器填充。
现在我的问题是,
考虑到我使用的是带 -O3 的 GCC 或 GCC-7,编译器可以将表达式优化到什么程度?例如,如果 A_64 变为全零(可能以 2^{-64} 的概率发生)那么我们不需要计算 eqn.2 的第一部分然后 O_64 等于 D_64 & E_64 & F_64。 c编译器是否可以优化这种方式?我们必须记住,这些值是在运行时填充的,布尔表达式有大约 120 个变量。
处理器是否可以在运行时进行这样的优化(列表 1)?由于我的布尔表达式很长,执行将大量流水线化,现在如果出现这种情况,处理器是否可以从流水线中拉出一个操作?
如果问题的任何部分无法理解,请告诉我。
感谢您的帮助。
Is it possible for a c compiler to optimize such a way?
允许这样做,但可能不会。总的来说没什么收获。如果表达式的一部分静态已知为零,则将使用它。但是在按位计算中插入分支几乎总是适得其反,而且我从未见过编译器将一系列 AND 判断为 "long enough to be worth inserting an early-out"(当然,您当然可以手动这样做)。如果你需要一个硬性保证,我当然不能给你,如果你想确定,你应该经常检查程序集。
它可能会做的(至少对于更长的表达式)是重新关联表达式以获得更多的指令级并行性。所以这样的代码可能不会只是两个长的(但彼此平行)的依赖 AND 链,而是被分成更多的链。那仍然不会使时间取决于值。
Is it possible for a for a processor to do such an optimization during runtime?
非常假设是的。据我所知,没有处理器架构可以做到这一点。这将是一个稍微棘手的机制,并且作为一般规则,它几乎无济于事。
假设它可以这样工作:当查找 AND 指令的操作数并且发现其中一个(或两个)被重命名为硬连线零寄存器时,重命名器可以立即重命名目的地也为零(而不是为结果分配一个新寄存器),有效地为该 AND 指令提供 0 延迟。标志输出也将是已知的,因此甚至不必执行 µop。它大致是复制消除和归零习语之间的交叉。
该机制甚至不会触发,除非其中一个输入使用归零惯用语设置为零,如果输入 意外 零而不会被检测到。它也不会完全消除冗余 AND 指令的影响,它们仍然必须经过(大部分)处理器的前端,即使只是为了发现它们根本不需要执行.
我想计算一个布尔表达式。为了便于理解,我们假设表达式是
O=(A & B & C) | ( D & E & F)---(eqn. 1),
这里A、B、C、D、E、F是随机比特。现在,由于我的目标平台是支持 64 位数据类型的高端英特尔 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 和 [=40 中的值=].这些值在运行时使用随机生成器填充。
现在我的问题是,
考虑到我使用的是带 -O3 的 GCC 或 GCC-7,编译器可以将表达式优化到什么程度?例如,如果 A_64 变为全零(可能以 2^{-64} 的概率发生)那么我们不需要计算 eqn.2 的第一部分然后 O_64 等于 D_64 & E_64 & F_64。 c编译器是否可以优化这种方式?我们必须记住,这些值是在运行时填充的,布尔表达式有大约 120 个变量。
处理器是否可以在运行时进行这样的优化(列表 1)?由于我的布尔表达式很长,执行将大量流水线化,现在如果出现这种情况,处理器是否可以从流水线中拉出一个操作?
如果问题的任何部分无法理解,请告诉我。 感谢您的帮助。
Is it possible for a c compiler to optimize such a way?
允许这样做,但可能不会。总的来说没什么收获。如果表达式的一部分静态已知为零,则将使用它。但是在按位计算中插入分支几乎总是适得其反,而且我从未见过编译器将一系列 AND 判断为 "long enough to be worth inserting an early-out"(当然,您当然可以手动这样做)。如果你需要一个硬性保证,我当然不能给你,如果你想确定,你应该经常检查程序集。
它可能会做的(至少对于更长的表达式)是重新关联表达式以获得更多的指令级并行性。所以这样的代码可能不会只是两个长的(但彼此平行)的依赖 AND 链,而是被分成更多的链。那仍然不会使时间取决于值。
Is it possible for a for a processor to do such an optimization during runtime?
非常假设是的。据我所知,没有处理器架构可以做到这一点。这将是一个稍微棘手的机制,并且作为一般规则,它几乎无济于事。
假设它可以这样工作:当查找 AND 指令的操作数并且发现其中一个(或两个)被重命名为硬连线零寄存器时,重命名器可以立即重命名目的地也为零(而不是为结果分配一个新寄存器),有效地为该 AND 指令提供 0 延迟。标志输出也将是已知的,因此甚至不必执行 µop。它大致是复制消除和归零习语之间的交叉。
该机制甚至不会触发,除非其中一个输入使用归零惯用语设置为零,如果输入 意外 零而不会被检测到。它也不会完全消除冗余 AND 指令的影响,它们仍然必须经过(大部分)处理器的前端,即使只是为了发现它们根本不需要执行.