gpt4 book ai didi

c++ - 为什么 'simplified' 代码没有向量化

转载 作者:行者123 更新时间:2023-12-01 11:55:47 24 4
gpt4 key购买 nike

我实现了以下代码,将 32 个字节的输入转换为大写:
版本 1:

void to_upper(char* input) {
for (int i = 0; i < 32; ++i) {
input[i] = (input[i] >= 'a' && input[i] <= 'z') ? input[i] - 32 : input[i];
}
}
版本 2:
void to_upper(char* input) {
for (int i = 0; i < 32; ++i) {
if (input[i] >= 'a' && input[i] <= 'z') {
input[i] = input[i] - 32; // same for: input[i] -= 32;
}
}
}
第一个版本被自动矢量化,第二个没有。该行为在 clang 和 gcc 中是一致的。此外,我也在 Rust 中实现了这两个版本,并且 Rust 编译器执行相同的操作,版本 1 自动矢量化,版本 2 不是。
是什么限制了编译器矢量化第二个版本?

最佳答案

基本上优化传递更难识别第二个循环中的条件分配。
在第一种情况下,GCC 生成一个稍微不同的中间表示,它允许 if-conversion pass 将代码转换为可向量化的形式:

  <bb 3>:
# i_18 = PHI <i_14(4), 0(2)>
# ivtmp_24 = PHI <ivtmp_21(4), 32(2)>
_6 = (sizetype) i_18;
_7 = input_5(D) + _6;
_8 = *_7;
_9 = (unsigned char) _8;
_10 = _9 + 159;
_11 = _9 + 224;
iftmp.0_12 = (char) _11;
iftmp.0_2 = _10 <= 25 ? iftmp.0_12 : _8;
*_7 = iftmp.0_2;
i_14 = i_18 + 1;
ivtmp_21 = ivtmp_24 - 1;
if (ivtmp_21 != 0)
goto <bb 4>;
else
goto <bb 5>;
而在第二种情况下,代码包含使分析复杂化和中断矢量化的虚假跳转:
  <bb 3>:
# i_15 = PHI <i_14(6), 0(2)>
# ivtmp_26 = PHI <ivtmp_25(6), 32(2)>
_5 = (sizetype) i_15;
_7 = input_6(D) + _5;
_8 = *_7;
_9 = (unsigned char) _8;
_10 = _9 + 159;
if (_10 <= 25)
goto <bb 4>;
else
goto <bb 5>;

<bb 4>:
_11 = _9 + 224;
_12 = (char) _11;
*_7 = _12;

<bb 5>:
i_14 = i_15 + 1;
ivtmp_25 = ivtmp_26 - 1;
if (ivtmp_25 != 0)
goto <bb 6>;
else
goto <bb 7>;
许多优化 channel 作为模式匹配器工作,可以识别和优化常见情况,因此我不会对这种行为感到惊讶。
您可以尝试在 GCC tracker 中提交错误.

关于c++ - 为什么 'simplified' 代码没有向量化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63004404/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com