放荡不羁的bug - __builtin_ctzl
type: channel
link: http://blog.bug-maker.com/tag/builtin_ctzl/
items: MSVC中的_BitScanForward和GCC中的__builtin_ctzl

MSVC中的_BitScanForward和GCC中的__builtin_ctzl
type: item
date: 2023-03-29T19:37:00+08:00
description: 问题索博尔算法中用到了_BitScanForward这个函数，在做统信UOS适配的时候发现这个函数是MSVC专有的，百度了一下linux下对应的有__builtin_ctz相关的系列函数头文件引用*winlinux头文件intrin.hx86intrin.h函数_BitScanForward__builtin_ctzl代码对比win#include <iostream> #include <intrin.h> using namespace std; #pragma intrinsic(_BitScanForward) static const unsigned QRNG_NDMS = 32; struct { unsigned __int64 uValue; unsigned uPrevSeed; } m_prev[QRNG_NDMS]; unsigned __int64 cjn[QRNG_NDMS][63] = { 0 }; int main() { unsigned long mask = 0; unsigned long index; unsigned char isNonzero; unsigned m_uCurSeed = 2048,m_uCurDim; m_uCurDim = 0; unsigned grayCode = (m_uCurSeed >> 1) ^ m_uCurSeed; unsigned changedBits = m_prev[m_uCurDim].uPrevSeed ^ grayCode; unsigned long uBit; while (_BitScanForward(&uBit, changedBits)) { cout << uBit << endl << changedBits <<endl; m_prev[m_uCurDim].uValue ^= cjn[m_uCurDim][uBit]; changedBits &= ~(1 << uBit); } cout << uBit << endl << changedBits <<endl; return 0; }Linux#include <iostream> #include <x86intrin.h> using namespace std; static const unsigned QRNG_NDMS = 32; struct { unsigned long long uValue; unsigned uPrevSeed; } m_prev[QRNG_NDMS]; unsigned long long cjn[QRNG_NDMS][63] = { 0 }; int main(int, char**) { unsigned long mask = 0; unsigned long index = 0; unsigned char isNonzero; unsigned m_uCurSeed = 2048,m_uCurDim; m_uCurDim = 0; unsigned grayCode = (m_uCurSeed >> 1) ^ m_uCurSeed; unsigned changedBits = m_prev[m_uCurDim].uPrevSeed ^ grayCode; unsigned long uBit; cout << __builtin_ctzl(10) << endl; while (true) { uBit = __builtin_ctzl(changedBits); if(uBit >= 64){ break; } cout << uBit << endl << changedBits <<endl; m_prev[m_uCurDim].uValue ^= cjn[m_uCurDim][uBit]; changedBits &= ~(1 << uBit); } cout << uBit << endl << changedBits <<endl; }