在我的程序中,我需要快速遍历作为数组实现的循环列表。循环的最慢部分恰好是剩余操作(除法!),该操作可确保索引不会落到数组的远端。因此,我巧妙地将循环分为三个部分,以避免其余操作。
为减少代码重复,我为如下所示的循环结构创建了一个C宏和一个C ++模板:
template <typename F>
static inline void
for_loop_pairs(int at,int loops,const F fun) {
int right = MIN(loops,N - at - 1);
int left = loops - right;
while (right) {
int next = at + 1;
fun(at,next);
at = next;
next++;
right--;
}
if (left) {
fun(N - 1,0);
left--;
at = 0;
while (left) {
int next = at + 1;
fun(at,next);
at = next;
next++;
left--;
}
}
}
#define FOR_LOOP_PAIRS(at,loops,fun) \
int right = MIN(loops,N - at - 1); \
int left = loops - right; \
int k0 = at; \
while (right) { \
int k1 = k0 + 1; \
fun; \
k0 = k1; \
k1++; \
right--; \
} \
if (left) { \
k0 = N - 1; \
int k1 = 0; \
fun; \
left--; \
k0 = 0; \
while (left) { \
k1 = k0 + 1; \
fun; \
k0 = k1; \
k1++; \
left--; \
} \
}
N
是数组中的项目数。要调用宏和for循环,我使用:
FOR_LOOP_PAIRS(start,{
// Do stuff with k0 and k1,which are the indices.
});
for_loop_pairs(start,[&](int k0,int k1) {
// Do stuff with k0 and k1 which are the indices.
});
使用模板的版本更干净,但也慢了5%,这是不可接受的。我的问题是我做错了什么?我希望模板代码产生与宏完全相同的代码。
编译命令:g++ -Wall -Werror -fPIC -march=native -mtune=native -O3 -fomit-frame-pointer fname.cpp
gcc版本7.4.0。