这可能与语言无关,但我是从 C++ 背景问的。
我正在为嵌入式系统(AVR,8 位)编写一个环形缓冲区。让我们假设:
const uint8_t size = /* something > 0 */;
uint8_t buffer[size];
uint8_t write_pointer;
如果缓冲区是 2 的幂,那么有一个巧妙的技巧可以&
对写入和读取指针size-1
进行有效的无分支翻转,如下所示:size
// value = buffer[write_pointer];
write_pointer = (write_pointer+1) & (size-1);
但是,如果大小不是 2 的幂,则回退可能是将指针(即索引)与大小进行比较并进行条件重置:
// value = buffer[write_pointer];
if (++write_pointer == size) write_pointer ^= write_pointer;
由于重置很少发生,因此对于任何分支预测都应该很容易。
虽然这假设指针需要在内存中向前推进。虽然这很直观,但它需要size
在每次迭代中加载。我假设在常规情况下颠倒顺序(向后推进)会产生更好的 CPU 指令(即),因为仅在重置期间才需要。jump if not zero
size
// value = buffer[--write_pointer];
if (write_pointer == 0) write_pointer = size;
所以
TL; DR:我的问题是:由于缓存未命中(因为不能简单地向前读取内存),通过内存向后行进是否会对执行时间产生负面影响,或者这是一个有效的优化?