首页 > 解决方案 > _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。

标签: c++opencl

解决方案


您可以对浮点数进行异或运算_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 的潜力。


推荐阅读