如果你在一个快速乘法的架构上,有没有办法在编译时检查?

mac*_*ord 11 c cpu-architecture

C代码是否有任何方法可以判断它是否在乘法快速的架构上编译?是否有一些宏__FAST_MULT__或在这些架构上定义的东西?

例如,假设您正在实现一个函数,通过shift-and-add方法确定64位整数的汉明权重.有两种最佳算法:一种需要17次算术运算,而另一种只需要12次,但其中一种是乘法运算.因此,如果您在硬件​​上运行,第二种算法的速度提高了30%,其中乘法所需的时间与添加时间相同 - 但是,在将乘法实现为重复加法的系统上,要慢得多.
因此,在编写这样的函数时,能够在编译时检查是否是这种情况并在适当时在两种算法之间切换是有用的:

unsigned int popcount_64(uint64_t x) {
    x -= (x >> 1) & 0x5555555555555555;                             // put count of each 2 bits into those 2 bits
    x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); // put count of each 4 bits into those 4 bits
    x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f;                        // put count of each 8 bits into those 8 bits
#ifdef __FAST_MULT__
    return (x * 0x0101010101010101)>>56;                            // returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
#else // __FAST_MULT__
    x += x >>  8;                                                   // put count of each 16 bits into their lowest 8 bits
    x += x >> 16;                                                   // put count of each 32 bits into their lowest 8 bits
    x += x >> 32;                                                   // put count of each 64 bits into their lowest 8 bits
    return x & 0x7f;
#endif // __FAST_MULT__
}
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

*是的,我知道这些__builtin_popcount()功能; 这只是一个例子.

Joh*_*ger 7

C代码是否有任何方法可以判断它是否在乘法快速的架构上编译?是否有一些宏__FAST_MULT__或在这些架构上定义的东西?

不,标准C不提供任何此类设施.特定的编译器可能提供扩展这样的东西,但我并没有特别注意到它实际上做了什么.

这种事情可以在构建配置期间进行测试,例如通过Autoconf或CMake,在这种情况下,您可以在适当的时候自己提供符号.

或者,某些C编译器肯定会提供指示编译代码的体系结构的宏.您可以结合对各种机器架构细节的了解来使用它来在两种算法之间进行选择 - 毕竟这就是这些宏的用途.

或者,您可以依赖构建程序的人员,通过配置选项,通过定义宏或其他任何内容来选择.

  • 对于Autoconf/Cmake来说,这通常是最好的选择,如果你真的想要从你的应用程序中挤出最后一点性能 - 在第一次启动时通过预编译的助手二进制文件进行动态的全自动编译.这些不需要"快",他们只需要触发一个构建:-) (2认同)