Tob*_*999 5 c c++ integer sse avx
我有一个布尔表达式,我已设法在SSE2中实现.现在我想尝试在AVX中实现它,在并行性增加中利用额外的因子2(从128位SIMD类型到256).但是,AVX不支持整数操作(AVX2可以使用,但我正在使用Sandy Bridge处理器,因此它目前不是一个选项).但是,由于存在用于按位运算的AVX内在函数.我想我可以尝试将我的整数类型转换为浮点类型并查看它是否有效.
第一次测试是成功的:
__m256 ones = _mm256_set_ps(1,1,1,1,1,1,1,1);
__m256 twos = _mm256_set_ps(2,2,2,2,2,2,2,2);
__m256 result = _mm256_and_ps(ones, twos);
Run Code Online (Sandbox Code Playgroud)
我正在按照自己的意愿来训练所有的0.模拟AND'ing两个而不是我得到2的结果.但是当相应地尝试11 XOR 4时:
__m256 elevens = _mm256_set_ps(11,11,11,11,11,11,11,11);
__m256 fours = _mm256_set_ps(4,4,4,4,4,4,4,4);
__m256 result2 = _mm256_xor_ps(elevens, fours);
Run Code Online (Sandbox Code Playgroud)
结果是6.46e-46(即接近0)而不是15.模拟地做11 OR 4给出的值为22而不是15应该是.我不明白为什么会这样.这是一个我错过的bug还是一些配置?
我实际上期待我使用float的假设,好像它们是整数不起作用,因为初始化为浮点值的整数可能实际上不是精确值而是近似值.但即便如此,我对我得到的结果感到惊讶.
有没有人有这个问题的解决方案或者我必须升级我的CPU才能获得AVX2支持吗?
第一次测试是偶然的.
1作为浮点数是0x3f800000,2是0x40000000.一般来说,它不会那样工作.
但你绝对可以做到这一点,你必须确保你正在使用正确的位模式.不要将整数转换为浮点数 - 重新解释它们.这对应于内在函数_mm256_castsi256_ps,或者将内存存储到内存中并将它们作为浮点数读取(这不会改变它们,通常只有数学运算关心浮点数的意思,其余的工作原始位模式,检查列表指令可以确保的例外情况).
您不需要AVX2即可使用AVX整数加载和存储操作:请参阅intel内部指南。因此,您可以使用AVX加载整数,重新解释转换为浮点数,使用浮点按位运算,然后重新解释转换为int。重新解释广播不生成任何指令,它们只是使编译器满意。尝试这个:
//compiled and ran on an Ivy Bridge system with AVX but without AVX2
#include <stdio.h>
#include <immintrin.h>
int main() {
int a[8] = {0, 2, 4, 6, 8, 10, 12, 14};
int b[8] = {1, 1, 1, 1, 1, 1, 1, 1};
int c[8];
__m256i a8 = _mm256_loadu_si256((__m256i*)a);
__m256i b8 = _mm256_loadu_si256((__m256i*)b);
__m256i c8 = _mm256_castps_si256(
_mm256_or_ps(_mm256_castsi256_ps(a8), _mm256_castsi256_ps(b8)));
_mm256_storeu_si256((__m256i*)c, c8);
for(int i=0; i<8; i++) printf("%d ", c[i]); printf("\n");
//output: 1 3 5 7 9 11 13 15
}
Run Code Online (Sandbox Code Playgroud)
当然,正如Mystical指出的那样,这可能不值得做,但这并不意味着您做不到。
| 归档时间: |
|
| 查看次数: |
2137 次 |
| 最近记录: |