我有一个像这样的数组:
{
1, 2, 3, 4,
5, 6, 7, 8,
9,10,11,12,
13,14,15,16
}
我需要以锯齿形方式迭代它,例如1,2,3,4,8,7,6,5,9...
这很简单,但是开销空间很小,所以我需要它尽可能节省时间。每个额外的周期在这里都很重要。
这就是我现在拥有的:
#define send_colors_zigzag(io, colorz, width, height) do { \
for(int8_t y = 0, uu=0, a=1; y < (height); y++, uu+=width, a *= -1) { \
uint8_t uup = uu + (a < 0 ? width : 0); \
for(uint8_t x = 0; x < (width); x++) { \
uint8_t pos = uup + a*x; \
const color_t clr = (colorz)[pos]; \
send_one_color(io_pack(io), clr); \
} \
} \
} while(0)
send_one_color
是一个宏,它扩展为各个位的循环,我不想在这个宏中重复它两次(需要保持它很小)。
我有理由将其作为宏来执行,io
和 io_pack
是引脚别名的一些魔法,这是常规函数无法完成的。
我相信它循环正确,但它不够快(因此无法使用)。
我正在开发 8 位微型处理器,16MHz。
仅供引用,此版本有效(但大型内部宏重复两次,我想避免):
#define send_colors_zigzag(io, colorz, width, height) do { \
int8_t x; \
for(int8_t y = 0; y < (height); y++) { \
for(x = 0; x < (width); x++) { \
send_one_color(io_pack(io), (colorz)[y*width + x]); \
} \
y++; \
for(x = width-1; x >=0; x--) { \
send_one_color(io_pack(io), (colorz)[y*width + x]); \
} \
} \
} while(0)
最佳答案
这是一种尽可能避免算术的方法,尤其是在内循环中。
color_t* p = (colorz);
for (int8_t y = 0; y < (height); y++) {
int8_t inc = y & 1 ? -1 : 1;
if (y) {
p += (width) + inc;
}
for (int8_t x = 0; x < (width); x++) {
send_one_color(io_pack(io), *p);
p += inc;
}
}
如果 height
是偶数,或者如果您不介意未定义的行为(因为 p
指向超出 的末尾),则可以使用此变体节省一些周期>colorz
):
color_t* p = (colorz);
for (int8_t y = 0; y < (height); y++) {
int8_t inc = y & 1 ? -1 : 1;
for (int8_t x = 0; x < (width); x++) {
send_one_color(io_pack(io), *p);
p += inc;
}
p += (width) - inc;
}
关于c - Zig-zag 迭代数组 - 速度优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29193419/