c++ - _mm_xor_pd 失败,产品 = 0
问题描述
我正在开始学习转换我在整数数学中工作的一些代码,以利用更快的 GPU 浮点运算。我不明白为什么我不能让 _mm_xor_pd() 工作。仅出于测试目的,我已将相同的值填充到两个向量中,如下所示:
__m128d shift04 = _mm_set1_pd(16);
__m128d v1 = _mm_set1_pd(0x33F4A032);
__m128d k0 = _mm_set1_pd(0x6A6BA9EF);
__m128d j = _mm_add_pd(_mm_mul_pd(v1,shift04),k0); // j = (v1 << 4) + k0
__m128d k = _mm_add_pd(v1,sum); // k = v1 + sum
__m128d l = _mm_xor_pd(j,k); // l = j ^ k
我很欣赏上面的代码很糟糕,但它仅用于基本测试,所以请耐心等待。l[0]
和的值l[1]
是0
?
j[0]
正确等于0xa9b5ad0f
k[0]
正确等于0xd22c19eb
l[0]
应该相等0x7b99b4e4
,但上面的代码产生0x0000000
.
我目前假设这是因为您通常不能对浮点进行异或运算,但该函数清楚地表明了它的作用。我错了吗?
Ubuntu 19.1、G++ 版本 9.2.1、Radeon VII 和 Intel I7 2600k。
解决方案
您可以对浮点数进行异或运算_mm_xor_pd
,但实际上是对浮点数进行异或运算,它不会将浮点数转换为整数并对它们进行异或运算。浮点数比整数更复杂,例如乘以 16 不会移动位,它将指数增加 4 并将其他位留在原处(非正规数或指数溢出或其他一些边缘情况除外)。
这里的结果可能不是零(我无法测试它,因为sum
没有定义)而是很小,因此将其转换为整数会导致零。
转换一些我在整数数学中工作的代码,以利用更快的 GPU 浮点运算
幸运的是,还有整数 SIMD,所以你可以使用它而不是与浮点数对抗。
例如:
__m128i v1 = _mm_set1_epi32(0x33F4A032);
__m128i k0 = _mm_set1_epi32(0x6A6BA9EF);
__m128i j = _mm_add_epi32(_mm_slli_epi32(v1, 4), k0); // j = (v1 << 4) + k0
__m128i k = _mm_add_epi32(v1, sum); // k = v1 + sum
__m128i l = _mm_xor_si128(j, k); // l = j ^ k
请记住,尽管 SIMD 的要点是矢量化,但在每个“通道”中始终使用相同的值并不是很有用,这只会浪费 3/4 的潜力。
推荐阅读
- c# - 为什么没有分配给变量的 LINQ 查询没有编译器警告
- c# - 将复选框状态绑定到 WPF 中的 BitArray
- excel - 使用Dir函数时找不到excel VBA“运行时错误1004”文件
- python - 为什么某些python代码的包装器和包装函数是相同的。
- python - 使用 ID/key/value 将 dict 转换为三列数据框
- yii - Yii2 在哪里捕获从引导程序模块抛出的异常?
- php - 检查电子邮件是否在 PHP 中的 Mysql 数据库中
- audio - Flutter - 如何播放环境声音?
- ruby-on-rails - 不允许的参数 & 无法显示嵌套的 fields_for
- html - 仅从 webelemnt 获取内部文本