c - 如何使用 MSVC 内在函数来获得这个 GCC 代码的等价物?

标签 c visual-c++ intrinsics

以下代码在 GCC 中调用 clz/ctz 的内置函数,并且在其他系统上具有 C 版本。显然,如果系统具有内置的 clz/ctz 指令,如 x86 和 ARM,则 C 版本有点次优。

#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

我需要调用什么函数,我需要包含哪些 header 等等,以便在此处为 MSVC 添加适当的 ifdef?我已经看过 this page ,但我不完全确定#pragma 的用途(它是必需的吗?)以及它对编译的 MSVC 版本要求有什么限制。作为一个并不真正使用 MSVC 的人,我也不知道这些内在函数在其他体系结构上是否具有 C 等价物,或者在#defining 它们时是否也必须#ifdef x86/x86_64。

最佳答案

从 sh0dan 代码中跳出,应该像这样更正实现:

#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

如代码中所述,如果值为 0,则 ctz 和 clz 均未定义。在我们的抽象中,我们将 __builtin_clz(value) 固定为 (value?__builtin_clz(value):32 ) 但这是一个选择

关于c - 如何使用 MSVC 内在函数来获得这个 GCC 代码的等价物?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/355967/

相关文章:

c++ - hiredis Redis 库是否为异步回调创建自己的线程

c - 服务器中的 accept() 函数似乎不接受来自客户端的新连接

c - 数组声明,并且不使用中间索引

visual-studio-2010 - 在 Visual Studio 中启动调试器时通过属性表更改 PATH

c++ - 使用/不使用内在函数填充 C++

编译错误 'incompatible pointer to integer conversion passing ' int (int, int )' to parameter of type ' int' [-Wint-conversion]"

c++ - 替换(或重新实现?)std::function 用于一些统计和测试

c++ - 如何通过 COM 公开通过结构化异常处理捕获的异常?

gcc - 使用 SSE2 内在函数和 gcc 内联汇编器

c++ - ICC 中的 -O3 搞乱了内在函数,与 -O1 或 -O2 或相应的手动组装一起使用