C语言 索引比指针更容易矢量化吗?



是否有任何示例(例如在 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 的背景下看待这个问题。指针样式本质上是强度降低的索引样式,因为加法被增量取代。这种减少在一段时间内对性能有利,但不再有益。

所以我的问题归结为是否存在编译器无法执行或逆转这种强度降低的情况。

另一种可能的情况是索引不是归纳变量。因此,相应的指针代码包括"任意跳转",并且由于过去迭代的"历史记录",转换循环变得更加困难。

只要不涉及重载operator [],下标表达式就被定义为与指针算术相同,然后取消引用结果 [expr.sub]/1。因此,只要两个版本确实是等效的,编译器通常应该能够同样很好地优化两个版本(我可能会认为编译器未能优化一个而不是另一个是性能错误(。话虽如此,请注意,有很多微妙之处,例如无符号算术的环绕行为,可以使迭代索引不完全等同于迭代指针......

相关内容

最新更新