【发布时间】:2013-06-07 10:48:31
【问题描述】:
我的问题类似于Can one unroll a loop when working with an integer template parameter?,但我想混合编译时间和运行时。具体来说,我在编译时知道一个常量NBLOCK,我想在变量start_block 上编写一个开关,该变量仅在运行时知道,其中NBLOCK 是开关中的条目数。这是我使用宏得到的结果:
#define CASE_UNROLL(i_loop) \
case i_loop : \
dst.blocks[i_loop+1] -= (load_unaligned_epi8(srcblock) != zero) & block1; \
srcblock += sizeof(*srcblock);
switch(start_block)
{
CASE_UNROLL(0);
#if NBLOCKS > 2
CASE_UNROLL(1);
#endif
#if NBLOCKS > 3
CASE_UNROLL(2);
#endif
#if NBLOCKS > 4
CASE_UNROLL(3);
#endif
...
...
#if NBLOCKS > 15
CASE_UNROLL(14);
#endif
#if NBLOCKS > 16
#error "Too many blocks"
#endif
}
我觉得它很丑。特别是如果我想将界限从 16 提高到 32。
我想知道是否可以使用一些模板元编程来编写它。困难的部分是,出于性能原因,使用跳转表而不是嵌套条件序列来编译开关至关重要。
请注意,这个问题与C++/C++11 - Switch statement for variadic templates? 非常相似,但据我了解,这里提出的解决方案是通过使用混合编译/调谐时间初始化函数指针数组来删除开关。我不能付钱给王子在这里调用一个函数。
如果需要一些讨厌的扩展,我正在使用 GCC。
【问题讨论】:
-
不,它不是重复的。就我而言,起点在运行时已知,终点在编译时已知。 GCC 能够展开代码,但它使用了很多跳转。这个版本要快得多,因为只有一次跳转。但是它使用宏。我宁愿写一个模板。
-
我问为什么?真的比编译后的代码快吗?
-
是的,速度提高了 30%。这里的开关在我的内部计算循环中。
标签: c++ templates c++11 switch-statement template-meta-programming