好的,我想要的是非常直接的:
到目前为止,这是我的代码(以2个宏的形式):
#define SETBIT(X,Y) X|=(1ULL<<(Y))
#define UNSETBIT(X,Y) X&=(~(1ULL<<(Y)))
他们都工作正常。事情是:
(两种操作都应该每秒执行数百万次,因此性能非常重要。)
答案 0 :(得分:6)
你可以通过摆脱宏来略微加快编译时间,但这就是它。比特小的速度足够快,所以它应该不是问题。
这是这样做的惯用方式,我不会改变一件事。
答案 1 :(得分:3)
这是在C中设置和清除位的标准方法。
如果您希望可能加速这些宏,您可以查看这些操作的Linux程序集实现。
例如,对于x86
:
http://lxr.linux.no/linux/arch/x86/include/asm/bitops.h
查找__clear_bit
和__set_bit
内联函数。
答案 2 :(得分:2)
这些宏是最优的和惯用语,因此如果要进行优化,编译器可能会识别这些表达式。
你可能获得的唯一加速是......如果有更好的选择,可以避免使用它们。如果您经常进行相同的多位操作(例如,打开位0,2和4),您可以通过执行所有这些操作来获得某些操作。单个或而不是使用多个SETBIT
s。
答案 3 :(得分:2)
首先,您应该将宏修复为:
#define SETBIT(X,Y) ( (X) |= 1ULL << (Y) )
#define UNSETBIT(X,Y) ( (X) &= ~(1ULL << (Y)) ) )
这样,像SETBIT(a, 2) + 1;
这样的代码会更像预期,SETBIT(1+a, 2);
会产生预期错误。
您可能永远不会以这种方式使用宏,但是额外的括号无论如何都是免费的,并且解决与宏相关的问题可以是这样的PITA,它总是将额外的()
或{}
放在宏周围
附加:使用内联汇编和CPU进行位旋转操作,假设Y
在编译时不可知,UNSETBIT可以更快,避免使用NOT ... Pseudocode:
X = X OR (0xFFFFFFFFFFFFFFFE ROL Y)
然后,虽然这些宏的效率与它一样高(C编译器应该将它们优化为理想的汇编指令),但您应该提供宏来操作几个位,例如:
#define SET2BITS(X, B1, B2) ( (X) |= 1ULL << (B1) | 1ULL << (B2) )
在某些情况下,使用内部表达式的函数式宏也可能更有效(尽管编译器优化可能会达到相同的最终结果):
#define BITSETVAL(X, B) ( (X) | 1ULL << (B) )