Tag: avx

使用AVX与NaN比较

我正在尝试使用英特尔的AVX内在函数为BPSK创建一个快速解码器。 我有一组复数表示为交错浮点数,但由于BPSK调制,只需要实部(或偶数索引浮点数)。 当x < 0时,每个浮点x映射到0 ,如果x >= 0 ,则映射到1 。 这是使用以下例程完成的: static inline void normalize_bpsk_constellation_points(int32_t *out, const complex_t *in, size_t num) { static const __m256 _min_mask = _mm256_set1_ps(-1.0); static const __m256 _max_mask = _mm256_set1_ps(1.0); static const __m256 _mul_mask = _mm256_set1_ps(0.5); __m256 res; __m256i int_res; size_t i; gr_complex temp; float real; for(i = 0; i 0, […]

确定__m256值的SIMD通道的最小值

我知道通常应避免跨SIMD通道的操作。 但是,有时必须这样做。 我正在使用AVX2内在函数,并在__m256中有8个浮点值。 我想知道这个向量中的最低值,并使问题复杂化:也就是在哪个插槽中。 我目前的解决方案是内存往返,我不喜欢: float closestvals[8]; _mm256_store_ps( closestvals, closest8 ); float closest = closestvals[0]; int closestidx = 0; for ( int k=1; k<8; ++k ) { if ( closestvals[k] < closest ) { closest = closestvals[ k ]; closestidx = k; } } 没有去往/从记忆中这样做的好方法是什么?

如何清除__m256值的高128位?

如何清除m2的高128位: __m256i m2 = _mm256_set1_epi32(2); __m128i m1 = _mm_set1_epi32(1); m2 = _mm256_castsi128_si256(_mm256_castsi256_si128(m2)); m2 = _mm256_castsi128_si256(m1); 不起作用 – 英特尔的_mm256_castsi128_si256内在文档说“结果向量的高位未定义”。 同时我可以在assembly中轻松完成: VMOVDQA xmm2, xmm2 //zeros upper ymm2 VMOVDQA xmm2, xmm1 当然我不想使用“和”或_mm256_insertf128_si256()等。

AVX将64位整数转换为64位浮点数

我想使用AVX将4个打包的64位整数转换为4个打包的64位浮点数。 我尝试过类似的东西: int_64t *ls = (int64_t *) _mm_malloc(256, 32); ls[0] = a; //… ls[3] = d; __mm256i packed = _mm256_load_si256((__m256i const *)ls); 哪个将显示在调试器中: (gdb) print packed $4 = {1234, 5678, 9012, 3456} 好的,到目前为止,但我能找到的唯一的演员/转换操作是_mm256i_castsi256_pd,这不能得到我想要的东西: __m256d pd = _mm256_castsi256_pd(packed); (gdb) print pd $5 = {6.0967700696809824e-321, 2.8053047370865979e-320, 4.4525196003213139e-320, 1.7074908720273481e-320} 我真正想看到的是: (gdb) print pd $5 = {1234.0, 5678.0, 9012.0, […]

ICC是否满足复数的乘法C99规范?

考虑这个简单的代码: #include complex float f(complex float x) { return x*x; } 如果使用英特尔编译器使用-O3 -march=core-avx2 -fp-model strict进行编译,则可以得到: f: vmovsldup xmm1, xmm0 #3.12 vmovshdup xmm2, xmm0 #3.12 vshufps xmm3, xmm0, xmm0, 177 #3.12 vmulps xmm4, xmm1, xmm0 #3.12 vmulps xmm5, xmm2, xmm3 #3.12 vaddsubps xmm0, xmm4, xmm5 #3.12 ret 这比你从gcc和clang获得的代码简单得多,而且比你在网上找到的用于乘以复数的代码简单得多。 例如,它没有明确地用于处理复杂的NaN或无穷大。 这个组件是否符合C99复数乘法的规范?

使用较新版本的SIMD版本是否可用?

当我可以使用SSE3或AVX时,可以使用SSE2或MMX等较旧的SSE版本 – 或者我还需要单独检查它们吗?

检查运行时是否支持SSE

我想检查运行时是否支持SSE4或AVX,以便我的程序可以利用特定于处理器的指令而无需为每个处理器创建二进制文件。 如果我可以在运行时确定它,我可以使用一个接口并在不同的指令集之间切换。

__m256类型的intel内在函数问题

我正在尝试测试一些英特尔内部函数,看看它们是如何工作的。 所以,我创建了一个函数来为我做这个,这是代码: void test_intel_256() { __m256 res,vec1,vec2; __M256_MM_SET_PS(vec1, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0); __M256_MM_SET_PS(vec1, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0); __M256_MM_ADD_PS(res,vec1,vec2); if (res[0] ==9 && res[1] ==9 && res[2] ==9 && res[3] ==9 && res[4] ==9 && res[5] ==9 && res[6] ==9 && res[7] ==9 ) printf(“Addition : OK!\n”); else […]

AVX / SSE版xorshift128 +

我正在努力制作最快的高质量RNG。 阅读http://xorshift.di.unimi.it/,xorshift128 +似乎是一个不错的选择。 C代码是 #include uint64_t s[ 2 ]; uint64_t next(void) { uint64_t s1 = s[ 0 ]; const uint64_t s0 = s[ 1 ]; s[ 0 ] = s0; s1 ^= s1 <> 17 ) ^ ( s0 >> 26 ) ) ) + s0; // b, c } 我不是SSE / AVX专家,但我的CPU支持SSE4.1 / SSE4.2 […]

使用单个AVX内在函数反转包含双精度的AVX寄存器

如果我有一个AVX寄存器,其中有4个双打,并且我想将其反向存储在另一个寄存器中,是否可以使用单个内部命令执行此操作? 例如:如果我在SSE寄存器中有4个浮点数,我可以使用: _mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3)); 我可以使用,也许是_mm256_permute2f128_pd()吗? 我不认为你可以用上面的内在来解决每个人的双重问题。