如果您处于乘法速度很快的体系结构中,C 中是否有任何方法可以在编译时检查?
Is there any way in C to check at compile time if you are on an architecture where multiplication is fast?
有什么方法可以让 C 代码判断它是否在乘法速度很快的体系结构上编译?是否有一些宏 __FAST_MULT__
或在这些架构上定义的东西?
例如,假设您正在实现一个函数,通过移位加法*确定 64 位整数的汉明权重。有two optimal algorithms for that:一个需要17次算术运算,而另一个只需要12次,但其中有一次是乘法运算。因此,第二个算法快 30%,if 你在硬件上 运行 乘法与加法花费相同的时间 - 但在乘法的系统上慢得多被实现为重复加法。
因此,在编写这样的函数时,能够在编译时检查是否是这种情况,并在适当的情况下在两种算法之间切换是很有用的:
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__
}
有什么办法吗?
* 是的,我知道 __builtin_popcount()
函数;这只是一个例子。
Is there any way for C code to tell whether it is being compiled on an architecture where multiplication is fast? Is there some macro __FAST_MULT__
or something which is defined on those architectures?
不,标准 C 不提供任何此类功能。特定的编译器可能会提供扩展之类的东西,但我并没有特别意识到实际上有什么。
这类事情可以在构建配置期间进行测试,例如通过 Autoconf 或 CMake,在这种情况下,您可以在适当的地方自己提供符号。
或者,一些 C 编译器确实提供了宏来指示编译代码所针对的体系结构。您可以将其与各种机器体系结构的细节知识结合使用,以在两种算法之间进行选择——毕竟,这就是此类宏的目的。
或者您可以依靠构建程序的人来选择,通过配置选项,通过定义宏或其他方式。
我认为没有专门针对快速乘法功能的预定义宏。
然而,有很多predefined compiler macros for different architectures所以如果你事先知道什么架构或CPU支持快速乘法指令,你可以使用那些宏请定义您自己的特定应用程序,表示快速乘法。
例如:
#if (defined __GNUC__ && defined __arm__ && defined __ARM_ARCH_'7'__) ||
(defined __CC_ARM && (__TARGET_ARCH_ARM == 7))
#define FAST_MULT
#endif
有什么方法可以让 C 代码判断它是否在乘法速度很快的体系结构上编译?是否有一些宏 __FAST_MULT__
或在这些架构上定义的东西?
例如,假设您正在实现一个函数,通过移位加法*确定 64 位整数的汉明权重。有two optimal algorithms for that:一个需要17次算术运算,而另一个只需要12次,但其中有一次是乘法运算。因此,第二个算法快 30%,if 你在硬件上 运行 乘法与加法花费相同的时间 - 但在乘法的系统上慢得多被实现为重复加法。
因此,在编写这样的函数时,能够在编译时检查是否是这种情况,并在适当的情况下在两种算法之间切换是很有用的:
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__
}
有什么办法吗?
* 是的,我知道 __builtin_popcount()
函数;这只是一个例子。
Is there any way for C code to tell whether it is being compiled on an architecture where multiplication is fast? Is there some macro
__FAST_MULT__
or something which is defined on those architectures?
不,标准 C 不提供任何此类功能。特定的编译器可能会提供扩展之类的东西,但我并没有特别意识到实际上有什么。
这类事情可以在构建配置期间进行测试,例如通过 Autoconf 或 CMake,在这种情况下,您可以在适当的地方自己提供符号。
或者,一些 C 编译器确实提供了宏来指示编译代码所针对的体系结构。您可以将其与各种机器体系结构的细节知识结合使用,以在两种算法之间进行选择——毕竟,这就是此类宏的目的。
或者您可以依靠构建程序的人来选择,通过配置选项,通过定义宏或其他方式。
我认为没有专门针对快速乘法功能的预定义宏。
然而,有很多predefined compiler macros for different architectures所以如果你事先知道什么架构或CPU支持快速乘法指令,你可以使用那些宏请定义您自己的特定应用程序,表示快速乘法。
例如:
#if (defined __GNUC__ && defined __arm__ && defined __ARM_ARCH_'7'__) ||
(defined __CC_ARM && (__TARGET_ARCH_ARM == 7))
#define FAST_MULT
#endif