小编dav*_*erd的帖子

设置任意大小整数的前导零位 C++

我想在标准 C++ 中将任何大小整数的前导零位设置为 1。

例如。

0001 0011 0101 1111 -> 1111 0011 0101 1111

我发现执行此操作的所有算法都需要相当昂贵的前导零计数。然而,这很奇怪。有非常快速且简单的方法来执行其他类型的位操作,例如:

 int y = -x & x; //Extracts lowest set bit, 1110 0101 -> 0000 0001

 int y = (x + 1) & x; //Will clear the trailing ones, 1110 0101 - > 1110 0100

 int y = (x - 1) | x; //Will set the trailing zeros, 0110 0100 - > 0110 0111
Run Code Online (Sandbox Code Playgroud)

因此,这让我认为必须有一种方法可以在由基本位运算符组成的一行简单代码中设置整数的前导零。请告诉我还有希望,因为现在我正在准备反转整数中的位顺序,然后使用设置尾随零的快速方法,然后再次反转整数以将前导零设置为 1。这实际上比使用前导零计数要快得多,但与上面的其他算法相比仍然相当慢。

 template<typename T>
 inline constexpr void reverse(T& x)
 {
    T rev …
Run Code Online (Sandbox Code Playgroud)

c++ optimization bit-manipulation dos x86-16

26
推荐指数
2
解决办法
2157
查看次数

逆立方根内在的 AVX-512 实现是 Microsoft 特有的吗?

我发现 MSVC 的 zmmintrin.h 副本定义了用于计算 __m512 32 位浮点向量和 __m512d 双向量的逆立方根的函数

 _mm512_invcbrt_ps();
 _mm512_invcbrt_pd();
Run Code Online (Sandbox Code Playgroud)

然而,这些函数在《Intel Intrinsics Guide》中没有出现: https: //software.intel.com/sites/landingpage/IntrinsicsGuide/

或者在英特尔更详细的开发指南中: https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/intrinsics/英特尔高级向量扩展的内在函数-512-英特尔-avx-512-指令/算术运算的内在函数-1/短向量数学库-svml-操作的内在函数/内在函数- for-root-function-operations-512-bit.html

不过,它们似乎没有在微软的网站上列出,请参阅:https://learn.microsoft.com/en-us/cpp/intrinsics/compiler-intrinsics ?view=msvc-160

我知道平方根反比有序列内在函数:

_mm512_invsqrt_ps();
_mm512_invsqrt_pd();
Run Code Online (Sandbox Code Playgroud)

我知道AVX有逆立方根序列内在函数:

 _mm256_invcbrt_ps();
 _mm256_invcbrt_pd();
Run Code Online (Sandbox Code Playgroud)

_mm512_invcbrt_ps()也是如此;和_mm512_invcbrt_pd(); 微软特定的还是英特尔真的忘记记录它们的内在函数之一?!?

c++ simd intrinsics visual-c++ avx512

5
推荐指数
0
解决办法
261
查看次数

尝试编写 Gerd Isenberg 的 Bit Scan Forward 的矢量化实现作为练习

我正在尝试编写 BSF 的矢量化实现作为练习,但我陷入困境,它不起作用。

算法:

 short bitScanForward(int16_t bb)
 {
     constexpr uint16_t two = static_cast<uint16_t>(2);
     constexpr uint16_t zero = static_cast<uint16_t>(0);
     uint16_t lsb;
     bb &= -bb;
     lsb = (unsigned short)bb
               | (unsigned short)(bb >> short(8));
     return static_cast<short>(((((((unsigned short)(bb >> 
       short(8)) != zero) * two)
    + ((lsb & unsigned short(0xf0f0)) != zero)) * two)
    + ((lsb & unsigned short(0xcccc)) != zero)) * two)
    + ((lsb & unsigned short(0xaaaa)) != zero);
}
Run Code Online (Sandbox Code Playgroud)

参见:Gerd Isenberg BSF

我的矢量代码:

 [[nodiscard]] inline __m128i _mm_cmpneq_epi16(const __m128i& a, const __m128i& …
Run Code Online (Sandbox Code Playgroud)

c++ sse bit-manipulation simd vectorization

2
推荐指数
1
解决办法
483
查看次数