这就是avx浮点位逻辑运算的原因
Which is the reason for avx floating point bitwise logical operations?
AVX允许对浮点数据类型__m256和__m256d进行和/或位逻辑运算。
然而,c++不允许对浮点数和双精度数进行位操作,这是合理的。如果我是对的,浮点数的内部表示没有保证,编译器是否会使用IEEE754,因此程序员不能确定浮点数的位是什么样子的。考虑这个例子:
#include <immintrin.h>
#include <iostream>
#include <limits>
#include <cassert>
int main() {
float x[8] = {1,2,3,4,5,6,7,8};
float mask[8] = {-1,0,0,-1,0,-1,0,0};
float x_masked[8];
assert(std::numeric_limits<float>::is_iec559);
__m256 x_ = _mm256_load_ps(x);
__m256 mask_ = _mm256_load_ps(mask);
__m256 x_masked_ = _mm256_and_ps(x_,mask_);
_mm256_store_ps(x_masked,x_masked_);
for(int i = 0; i < 8; i++)
std::cout << x_masked[i] << " ";
return 0;
}
假设使用IEEE754,由于-1的表示为0xffffffff,我希望输出为
1,0,0,4,0,6,0,0
而不是
1 0 0 1.17549e-38 0 1.17549e-38 0 0
因此我对内部表示的假设可能是错误的(或者我犯了一些愚蠢的错误)。
所以问题是:有没有一种方法可以让我使用浮点逻辑并且对结果有意义的事实是安全的?
如果你使用的是AVX内部函数,那么你就知道你使用的是IEEE754浮点数,因为这就是AVX所做的。
对浮点数进行的一些有意义的位操作如下:
- 选择,如Jens的回答,尽管在SSE4.1中,我们有
blendvps
及其亲属在一个指令 中完成该操作 - 绝对值(掩码)
- 负值 <
- 转移标志/gh>
- 提取指数(稀有)
主要用于操作符号,或选择性地将整个浮点数归零,而不是用于处理指数或有效位数的单个位-您可以这样做,但很少有用。
原因是在执行单元域之间切换可能会受到惩罚,因为在切换执行单元域时可能会绕过-delay -when-switching- execution_unit -domains和why-do-some-sse-mov-instructions-specify-that-they-move-floating-point-values。在本例中,从浮点AVX执行单元切换到整数AVX执行单元。
例如,你想比较浮点AVX寄存器x
和y
z = _mm256_cmp_ps(x, y, 1);
AVX寄存器z
包含布尔整数值(0或-1),然后您可以使用_mm256_and_ps
或_mm256_and_si256
进行逻辑与。但是_mm256_and_ps
保持在同一个执行单元,_mm256_and_si256
切换单元,这可能会导致旁路延迟。
编辑:关于浮点数的位运算符在c++中当然是可能的,有时是有用的。这里有一些简单的例子。
union {
float f;
int i;
} u;
u.i ^= 0x80000000; // flip sign bit of u.f
u.i &= 0x7FFFFFFF; // set sign bit to zero //take absolute value
程序员可以完全确定如何表示单精度浮点数。函数如何实现是另一回事。我已经利用位运算来实现符合IEEE-754的半精度浮点数。早在2003年,在IBM为此申请专利之前,我就已经使用了分支删除操作。
static inline __m128 _mm_sel_ps(__m128 a, __m128 b, __m128 mask ) {
b = _mm_and_ps( b, mask );
a = _mm_andnot_ps( mask, a );
return _mm_or_ps( a, b );
}
这个例子演示了如何使用SSE2删除一个浮点分支。使用AVX也可以达到同样的效果。如果您尝试(使用相同的技术)使用标量删除分支,由于上下文的切换,您将无法获得任何性能(适用于x86 -不适用于ARM,其中您有fpsel操作)
- 使用C++中的模板和运算符重载执行矩阵运算
- C++选择排序算法中的逻辑错误
- GCC本机矩阵运算库
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 用于AVX的ln(x)的实现,m256
- 位阵列上的快速AND运算
- 单精度矩阵运算的特征性能 AVX 与 SSE 没有区别?
- 使用 AVX 对两个 zmm(512 位)寄存器进行异或运算
- 提升有关逻辑运算的摩擦问题
- 在生成子序列时使用按位运算的逻辑是什么?
- C++随机数的逻辑运算结果
- 谁在Java或C++源代码中执行算术和逻辑运算
- 这个逻辑运算工作有什么问题?
- cout 中的逻辑运算
- 逻辑AND运算对流输出的作用
- 逻辑运算:我想使逻辑运算容易
- 这就是avx浮点位逻辑运算的原因
- C/ c++中对大文件二进制数据的逻辑运算
- 在现代x86_64 CPU上进行AVX/SSE幂运算需要多少时钟周期?