如何使用MSVC内在函数来得到这个GCC code的相同呢? [英] How to use MSVC intrinsics to get the equivalent of this GCC code?
问题描述
以下code调用内建函数在GCC CLZ / CTZ,并在其他系统上,已丙版本。很显然,将C版本有点不理想,如果系统有一个内建的CLZ / CTZ指令,像x86和ARM。
The following code calls the builtin functions for clz/ctz in GCC and, on other systems, has C versions. Obviously, the C versions are a bit suboptimal if the system has a builtin clz/ctz instruction, like x86 and ARM.
#ifdef __GNUC__
#define clz(x) __builtin_clz(x)
#define ctz(x) __builtin_ctz(x)
#else
static uint32_t ALWAYS_INLINE popcnt( uint32_t x )
{
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return x & 0x0000003f;
}
static uint32_t ALWAYS_INLINE clz( uint32_t x )
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return 32 - popcnt(x);
}
static uint32_t ALWAYS_INLINE ctz( uint32_t x )
{
return popcnt((x & -x) - 1);
}
#endif
我需要什么样的功能调用,这头我需要包括等添加适当的ifdef为MSVC在这里?我已经看了此页面,但我不完全知道什么使用#pragma是(需要它?)什么限制,它把对MSVC版本要求进行编译。正如有人谁不真正使用MSVC,我也不知道这些内在是否对其他架构ç的等价物或我是否#defining当他们的x86支持#ifdef / x86_64的为好。
What functions do I need to call, which headers do I need to include, etc to add a proper ifdef for MSVC here? I've already looked at this page, but I'm not entirely sure what the #pragma is for (is it required?) and what restrictions it puts on MSVC version requirements for compilation. As someone who doesn't really use MSVC, I also don't know whether these intrinsics have C equivalents on other architectures, or whether I have to #ifdef x86/x86_64 as well when #defining them.
推荐答案
从sh0dan code弹跳,实现应该这样进行修正:
Bouncing from sh0dan code, the implementation should be corrected like this :
#ifdef _MSC_VER
#include <intrin.h>
uint32_t __inline ctz( uint32_t value )
{
DWORD trailing_zero = 0;
if ( _BitScanForward( &trailing_zero, value ) )
{
return trailing_zero;
}
else
{
// This is undefined, I better choose 32 than 0
return 32;
}
}
uint32_t __inline clz( uint32_t value )
{
DWORD leading_zero = 0;
if ( _BitScanReverse( &leading_zero, value ) )
{
return 31 - leading_zero;
}
else
{
// Same remarks as above
return 32;
}
}
#endif
由于在code评论说,无论CTZ和CLZ是不确定的,如果值是0。在我们的抽象,我们固定 __ builtin_clz(值)
为(值__ builtin_clz(值):32)
,但它是一个选择
这篇关于如何使用MSVC内在函数来得到这个GCC code的相同呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!