Tag: sse

如何用最少的指令乘以两个四元数?

经过一番思考后,我想出了以下代码,用于使用SSE乘以两个四元数: #include /* SSE3 intrinsics */ /* multiplication of two quaternions (x, y, z, w) x (a, b, c, d) */ __m128 _mm_cross4_ps(__m128 xyzw, __m128 abcd) { /* The product of two quaternions is: */ /* (X,Y,Z,W) = (xd+yc-zb+wa, -xc+yd+za+wb, xb-ya+zd+wc, -xa-yb-zc+wd) */ __m128 wzyx = _mm_shuffle_ps(xyzw, xyzw, _MM_SHUFFLE(0,1,2,3)); __m128 baba = _mm_shuffle_ps(abcd, abcd, _MM_SHUFFLE(0,1,0,1)); […]

如何分配16byte内存对齐数据

我试图在一段代码上实现SSE矢量化,我需要将我的1D数组与16字节内存对齐。 但是,我已经尝试了几种方法来分配16byte内存对齐数据,但它最终是4byte内存对齐。 我必须使用Intel icc编译器。 这是我正在测试的示例代码: #include #include void error(char *str) { printf(“Error:%s\n”,str); exit(-1); } int main() { int i; //float *A=NULL; float *A = (float*) memalign(16,20*sizeof(float)); //align // if (posix_memalign((void **)&A, 16, 20*sizeof(void*)) != 0) // error(“Cannot align”); for(i = 0; i < 20; i++) printf("&A[%d] = %p\n",i,&A[i]); free(A); return 0; } 这是我得到的输出: &A[0] = […]

在GCC中使用不同版本的SSE内在函数的正确方法是什么?

我举一个例子来问我的问题。 现在我有一个名为do_something()的函数。 它有三个版本: do_something() , do_something_sse3()和do_something_sse4() 。 当我的程序运行时,它将检测CPUfunction(看它是否支持SSE3或SSE4)并相应地调用三个版本之一。 问题是:当我使用GCC构建程序时,我必须为do_something_sse4()设置-msse4以进行编译(例如,要包含头文件 )。 但是,如果我设置-msse4 ,则允许gcc使用SSE4指令, do_something_sse3()一些内在函数也会转换为某些SSE4指令。 因此,如果我的程序在仅支持SSE3(但没有SSE4)的CPU上运行,则在调用do_something_sse3()时会导致“非法指令”。 也许我有一些不好的做法。 你能提一些建议吗? 谢谢。

如何使用C中的SSE内部函数计算矢量点积

我试图将两个向量相乘,其中一个向量的每个元素乘以另一个向量的相同索引中的元素。 然后,我想总结得到的向量的所有元素以获得一个数字。 例如,对于向量{1,2,3,4}和{5,6,7,8},计算结果如下: 1 * 5 + 2 * 6 + 3 * 7 + 4 * 8 基本上,我正在采用两个向量的点积。 我知道有一个SSE命令来执行此操作,但该命令没有与之关联的内部函数。 此时,我不想在我的C代码中编写内联汇编,所以我只想使用内部函数。 这似乎是一个常见的计算,所以我很惊讶自己在Google上找不到答案。 注意:我正在针对特定的微架构进行优化,该架构最多支持SSE 4.2。 谢谢你的帮助。

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

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

对齐和SSE奇怪的行为

我尝试与SSE合作,我遇到了一些奇怪的行为。 我编写简单的代码来比较两个字符串与SSE内在函数,运行它并且它工作。 但后来我明白了,在我的代码中,一个指针仍未对齐,但我使用_mm_load_si128指令,这需要指针在16字节边界上对齐。 //Compare two different, not overlapping piece of memory __attribute((target(“avx”))) int is_equal(const void* src_1, const void* src_2, size_t size) { //Skip tail for right alignment of pointer [head_1] const char* head_1 = (const char*)src_1; const char* head_2 = (const char*)src_2; size_t tail_n = 0; while (((uintptr_t)head_1 % 16) != 0 && tail_n < […]

在_mm256_rsqrt_ps()中处理零

鉴于_mm256_sqrt_ps()相对较慢,并且我生成的值会立即被_mm256_floor_ps()截断,看看它似乎在做: _mm256_mul_ps(_mm256_rsqrt_ps(eightFloats), eightFloats); 是获得额外性能和避免管道停滞的方法。 不幸的是,零值,我当然得到崩溃计算1/sqrt(0) 。 围绕这个的最佳方法是什么? 我试过这个(有效并且更快),但是有更好的方法,还是我会在某些条件下遇到问题? _mm256_mul_ps(_mm256_rsqrt_ps(_mm256_max_ps(eightFloats, _mm256_set1_ps(0.1))), eightFloats); 我的代码用于垂直应用程序,因此我可以假设它将在Haswell CPU(i7-4810MQ)上运行,因此可以使用FMA / AVX2。 原始代码大约是: float vals[MAX]; int sum = 0; for (int i = 0; i < MAX; i++) { int thisSqrt = (int) floor(sqrt(vals[i])); sum += min(thisSqrt, 0x3F); } vals所有值都应该是整数值。 (为什么一切都不仅仅是int是一个不同的问题…)

调用always_inline’_mm_mullo_epi32’时内联失败:目标特定选项不匹配

我正在尝试使用使用SIMD内在函数的cmake编译C程序。 当我尝试编译它时,我得到两个错误 / usr / lib / gcc / x86_64-linux-gnu / 5 / include / smmintrin.h :326:1:错误:内联调用always_inline’_mm_mullo_epi32’失败:目标特定选项不匹配_mm_mullo_epi32(__ m128i __X,__ m128i __Y) / usr / lib / gcc / x86_64-linux-gnu / 5 / include / tmmintrin.h :136:1:错误:内联调用always_inline’_mm_shuffle_epi8’失败:目标特定选项不匹配_mm_shuffle_epi8(__ m128i __X,__ m128i __Y) 这个问题已经通过设置在这里解决了StackOverflow set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -msse4.1”) 我尝试了相同的和许多其他选项。 但我的项目仍然无法编译。 set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -msse4.1”) set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -sse4_1”) set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -march=nehalem”) […]

从RGB到BGRA的快速矢量化转换

在关于将RGB转换为RGBA和ARGB转换为BGR的一些先前问题的后续内容中,我想通过SSE加速RGB到BGRA的转换。 假设一台32位机器,并想使用内在函数 。 我很难将源缓冲区和目标缓冲区对齐以使用128位寄存器,并寻求其他精明的矢量化解决方案。 矢量化的例程如下…… void RGB8ToBGRX8(int w, const void *in, void *out) { int i; int width = w; const unsigned char *src= (const unsigned char*) in; unsigned int *dst= (unsigned int*) out; unsigned int invalue, outvalue; for (i=0; i<width; i++, src+=3, dst++) { invalue = src[0]; outvalue = (invalue<<16); invalue = src[1]; outvalue […]

从128位SSE向量加载和提取32位整数值的最有效方法是什么?

我正在尝试使用SSE内在函数来优化我的代码但是我遇到了一个问题,在我完成SSE内在函数操作以获得我想要的东西后,我不知道从向量中提取整数值的好方法。 有谁知道这样做的好方法? 我用C编程,我的编译器是gcc版本4.3.2。 感谢你的帮助。