Tag: simd

用于GCC划分的SIMD(SSE)指令

如果可能,我想使用SSE指令优化以下代码段: /* * the data structure */ typedef struct v3d v3d; struct v3d { double x; double y; double z; } tmp = { 1.0, 2.0, 3.0 }; /* * the part that should be “optimized” */ tmp.x /= 4.0; tmp.y /= 4.0; tmp.z /= 4.0; 这有可能吗?

移位n位的__m128i

我有一个__m128i变量,我需要将其n位的128位值移位,即_mm_srli_si128和_mm_slli_si128工作,但是在位而不是字节上。 这样做最有效的方法是什么?

最佳SSE无符号8位比较

我试图找到使用SSE执行8位无符号比较的最多方法(直到SSE 4.2)。 我正在研究的最常见的情况是比较> 0U,例如 _mm_cmpgt_epu8(v, _mm_setzero_si128()) // #1 (这当然也可以被认为是非零的简单测试。) 但我对更一般的情况也有点兴趣,例如 _mm_cmpgt_epu8(v1, v2) // #2 第一种情况可以使用各种不同的方法用2条指令实现,例如与0比较然后反转结果。 第二种情况通常需要3条指令,例如从两个操作数中减去128并执行带符号的比较。 (有关各种3种指令解决方案,请参阅此问题 。) 理想情况下,我正在寻找#1的单指令解决方案,以及#2的双指令解决方案。 如果这些都不可能,那么我也对在现代英特尔CPU(Sandy Bridge,Ivy Bridge,Haswell)上哪种各样的可能的2或3指令实现最有效的想法感兴趣。 到目前为止,案例#2的最佳实现: 比较等于无符号最大值和反转结果: #define _mm_cmpgt_epu8(v0, v1) \ _mm_andnot_si128(_mm_cmpeq_epi8(_mm_max_epu8(v0, v1), v1), \ _mm_set1_epi8(-1)) 两个算术指令+一个按位= 1.33吞吐量。 反转两个参数的符号位(==减去128)并使用带符号的比较: #define _mm_cmpgt_epu8(v0, v1) \ _mm_cmpgt_epi8(_mm_xor_si128(v0, _mm_set1_epi8(-128)), \ _mm_xor_si128(v1, _mm_set1_epi8(-128))) 一个算术指令+两个按位= 1.16吞吐量。 案例#1的最佳实现,源自上面的案例#2实现: 1。 #define _mm_cmpgtz_epu8(v0) \ _mm_andnot_si128(_mm_cmpeq_epi8(v0, _mm_set1_epi8(0)), \ […]

快速逐字节替换if

我有一个函数可以将二进制数据从一个区域复制到另一个区域,但前提是这些字节与特定值不同。 这是一个代码示例: void copy_if(char* src, char* dest, size_t size, char ignore) { for (size_t i = 0; i < size; ++i) { if (src[i] != ignore) dest[i] = src[i]; } } 问题是这对我目前的需求来说太慢了。 有没有办法以更快的方式获得相同的结果? 更新:基于答案,我尝试了两个新的实现: void copy_if_vectorized(const uint8_t* src, uint8_t* dest, size_t size, char ignore) { for (size_t i = 0; i < size; ++i) { […]

SIMD以下代码

如何在C中简化以下代码(当然使用SIMD内在函数)? 我无法理解SIMD内在函数,这会有很大帮助: int sum_naive( int n, int *a ) { int sum = 0; for( int i = 0; i < n; i++ ) sum += a[i]; return sum; }

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

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

测试两个__m128i变量之间的相等性

如果我想在两个__m128i变量之间进行逐__m128i测试,我是否需要使用SSE指令或者我可以使用== ? 如果没有,我应该使用哪条SSE指令?

gcc是否使用英特尔的SSE 4.2指令进行文本处理?

我在这里读到英特尔推出了加速字符串处理的SSE 4.2 instructions 。 从文章引用: SSE 4.2指令集首先在Intel的Core i7中实现,提供了字符串和文本处理指令(STTNI),它们利用SIMD操作处理字符数据。 尽管这些指令最初是为加速字符串,文本和XML处理而设计的,但这些指令的强大新function在这些域之外是有用的,值得重新审视众多应用程序的搜索和识别阶段,以利用STTNI来提高性能 gcc是否可以使用这些说明? 如果是这样,哪个版本? 如果没有,是否有任何开源库提供此function?

SSE(SIMD):通过标量乘以向量

我在程序中执行的常见操作是通过标量缩放矢量(V * s,例如[1,2,3,4] * 2 == [2,4,6,8])。 除了首先在向量中的每个位置加载标量(例如_mm_set_ps(2,2,2,2))然后相乘之外,是否有SSE(或AVX)指令来执行此操作? 这就是我现在所做的: __m128 _scalar = _mm_set_ps(s,s,s,s); __m128 _result = _mm_mul_ps(_vector, _scalar); 我在寻找像…… __m128 _result = _mm_scale_ps(_vector, s);

检查运行时是否支持SSE

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