是否有任何示例(例如在https://godbolt.org/上)当使用指针迭代而不是数组索引表示的算法时,CLang 会生成更糟糕的代码?例如,它可以在一种情况下矢量化/展开,但在另一种情况下不能?
在简单的例子中显然没关系。这是一个指针迭代样式:
while (len-- > 0) {
*dst++ = *src++;
}
这是索引样式的逻辑相同的代码:
while (idx != len) {
dst[idx] = src[idx];
idx++;
}
在这里忽略任何 UB 和/或关闭一个错误。
编辑:关于索引是糖的论点是无关紧要的,因为去糖不会改变算法风格。所以以下基于指针的代码仍然是索引样式:
while (idx != len) {
*(dst + idx) = *(src + idx);
idx++;
}
请注意,基于索引的循环只有 1 个变化变量,而基于指针的循环有 2 个,编译器必须推断它们总是一起变化。
您应该在https://en.wikipedia.org/wiki/Induction_variable和https://en.wikipedia.org/wiki/Strength_reduction的上下文中查看此内容。指针样式本质上是强度降低的索引样式,因为添加被增量替换。这种减少在一段时间内对性能有益,但不再有效。
所以我的问题归结为是否存在编译器无法执行或逆转这种强度降低的情况。
另一种可能的情况是索引不是归纳变量。因此,相应的指针代码包括“任意跳转”,并且由于过去迭代的“历史”,它在某种程度上更难以转换循环。