Tag: simd

SIMD代码比标量代码运行得慢

elma和elmc都是unsigned long数组。 res1和res1也是如此。 unsigned long simdstore[2]; __m128i *p, simda, simdb, simdc; p = (__m128i *) simdstore; for (i = 0; i > l) & 15; u2 = (elmc[i] >> l) & 15; for (k = 0; k < 20; k++) { //res1[i + k] ^= _mulpre1[u1][k]; //res2[i + k] ^= _mulpre2[u2][k]; simda = _mm_set_epi64x (_mulpre2[u2][k], […]

如何使用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()吗? 我不认为你可以用上面的内在来解决每个人的双重问题。

你有多快能进行线性搜索?

我正在寻找优化这种线性搜索: static int linear (const int *arr, int n, int key) { int i = 0; while (i = key) break; ++i; } return i; } 数组已排序,函数应返回大于或等于键的第一个元素的索引。 它们的数组不大(低于200个元素),并且会为大量搜索准备一次。 如果需要,可以在第n个之后将数组元素初始化为适当的数组,如果这样可以加快搜索速度。 不,不允许二进制搜索,只允许线性搜索。 编辑 :我在博客文章中总结了有关此主题的所有知识。

对齐和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 < […]

调用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”) […]

如何使用GNU C Vector Extensions从/向数组加载/存储?

我正在使用GNU C Vector Extensions ,而不是Intel的_mm_*内在函数。 我想做与英特尔的_m256_loadu_pd内在相同的事情。 逐个分配值很慢:gcc生成的代码有4个加载指令,而不是一个单独的vmovupd ( _m256_loadu_pd确实生成)。 typedef double vector __attribute__((vector_size(4 * sizeof(double)))); int main(int argc, char **argv) { double a[4] = {1.0, 2.0, 3.0, 4.0}; vector v; /* I currently do this */ v[0] = a[0]; v[1] = a[1]; v[2] = a[2]; v[3] = a[3]; } 我想要这样的东西: v = (vector)(a); 要么 v […]

从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。 感谢你的帮助。

使用SSE索引到数组

假设我有一个数组: uint8_t arr[256]; 和一个元素 __m128i x 包含16个字节, x_1, x_2, … x_16 我想有效地填充一个新的__m128i元素 __m128i y 使用arr中的值取决于x的值,这样: y_1 = arr[x_1] y_2 = arr[x_2] . . . y_16 = arr[x_16] 实现此目的的命令实质上是从非连续的一组存储器位置加载寄存器。 我看到这样一个命令的文档有一个痛苦的模糊记忆,但现在找不到它。 它存在吗? 在此先感谢您的帮助。