我实现了以下将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编译器也是这样做的,即第一个版本被自动向量化,第二个版本则没有。
什么因素限制了编译器对第二个版本进行向量化?
input[i] = input[i]
被优化掉了,但仍然导致条件跳转。这个跳转可能是它无法向量化的原因。 - Artyer