Tag: sse

使用SSE内在函数进行优化

我试图将一个循环转换为SSE内在函数。 我似乎已经取得了相当不错的进展,而且我的意思是它是在正确的方向但是我似乎在某处做了一些错误的翻译,因为我没有得到非sse代码导致的相同的“正确”答案。 我以4倍展开的原始循环如下所示: int unroll_n = (N/4)*4; for (int j = 0; j < unroll_n; j++) { for (int i = 0; i < unroll_n; i+=4) { float rx = x[j] – x[i]; float ry = y[j] – y[i]; float rz = z[j] – z[i]; float r2 = rx*rx + ry*ry + rz*rz + eps; […]

_mm_crc32_u64定义不明确

为什么世界上_mm_crc32_u64(…)定义是这样的? unsigned int64 _mm_crc32_u64( unsigned __int64 crc, unsigned __int64 v ); “crc32”指令总是累加32位CRC,而不是 64位CRC(毕竟,CRC32不是CRC64)。 如果机器指令CRC32 恰好具有64位目标操作数,则忽略高32位,并在完成时填充0,因此没有使用EVER具有64位目标。 我理解为什么英特尔允许在指令上使用64位目标操作数(为了均匀性),但如果我想快速处理数据,我想要一个尽可能大的源操作数(即如果剩下那么多数据,则为64位,尾部较小)并且始终是32位目标操作数。 但内在函数不允许使用64位源和32位目标。 注意其他内在函数: unsigned int _mm_crc32_u8 ( unsigned int crc, unsigned char v ); “crc”的类型不是8位类型,也不是返回类型,它们是32位。 为什么没有 unsigned int _mm_crc32_u64 ( unsigned int crc, unsigned __int64 v ); ? 英特尔指令支持这一点, 这是最有意义的内在因素。 有没有人有可移植的代码(Visual Studio和GCC)来实现后者的内在? 谢谢。 我的猜测是这样的: #define CRC32(D32,S) __asm__(“crc32 %0, %1” : […]

_mm_shuffle_ps()等效于整数向量(__m128i)?

_mm_shuffle_ps()内在函数允许将浮点输入交错为输出的低2浮点数和高2浮点数。 例如: R = _mm_shuffle_ps(L1, H1, _MM_SHUFFLE(3,2,3,2)) 将导致: R[0] = L1[2]; R[1] = L1[3]; R[2] = H1[2]; R[3] = H1[3] 我想知道整数数据类型是否有类似的内在可用? 有两个__m128i变量和一个掩码进行交错的东西? _mm_shuffle_epi32()内在函数只接受一个128位向量而不是两个向量。

如何使用SSE执行uint32 / float转换?

在SSE中有一个函数_mm_cvtepi32_ps(__m128i input) ,它接受32位宽的有符号整数( int32_t )的输入向量,并将它们转换为float s。 现在,我想将输入整数解释为未签名。 但是没有函数_mm_cvtepu32_ps ,我找不到一个实现。 你知道我在哪里可以找到这样的function,或者至少对实现有所暗示吗? 为了说明结果的差异: unsigned int a = 2480160505; // 10010011 11010100 00111110 11111001 float a1 = a; // 01001111 00010011 11010100 00111111; float a2 = (signed int)a; // 11001110 11011000 01010111 10000010

__m128i变量是零吗?

如何测试__m128i变量在SSE-2和更早版本的处理器上是否具有任何非零值?

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 […]

在包装的SSE浮标上翻转标志

我正在寻找在SSE寄存器中打包的所有四个浮点数上翻转符号的最有效方法。 我没有在英特尔架构软件开发手册中找到这样做的固有内容。 以下是我已经尝试过的事情。 对于每个案例,我在代码上循环了100亿次并且显示了挂号时间。 我试图至少匹配4秒,这需要我的非SIMD方法,这只是使用一元减号运算符。 [48秒] _mm_sub_ps( _mm_setzero_ps(), vec ); [32秒] _mm_mul_ps( _mm_set1_ps( -1.0f ), vec ); [9秒] union NegativeMask { int intRep; 漂浮fltRep; } negMask; negMask.intRep = 0x80000000; _mm_xor_ps(_mm_set1_ps(negMask.fltRep),vec); 编译器是带有-O3的gcc 4.2。 CPU是英特尔酷睿2双核处理器。

矢量化模运算

我正在尝试编写一些合理快速的组件向量加法代码。 我正在使用(签名,我相信)64位整数。 function是 void addRq (int64_t* a, const int64_t* b, const int32_t dim, const int64_t q) { for(int i = 0; i < dim; i++) { a[i] = (a[i]+b[i])%q; // LINE1 } } 我正在使用icc -std=gnu99 -O3 (icc以便我以后可以使用SVML)在IvyBridge(SSE4.2和AVX,但不是AVX2)上进行编译。 我的基线是从LINE1中删除%q 。 使用dim=11221184 100(迭代)函数调用需要1.6秒。 ICC自动矢量化SSE代码; 大。 我真的想做模块化的补充。 使用%q ,ICC不会自动向量化代码,并且它在11.8秒(!)内运行。 即使忽略了之前尝试的自动矢量化,这似乎仍然过分。 由于我没有AVX2,因此使用SSE进行矢量化需要SVML,这也许就是ICC没有自动矢量化的原因。 无论如何,这是我尝试对内循环进行矢量化: __m128i qs = _mm_set1_epi64x(q); for(int i […]

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], […]

如何将像素结构加载到SSE寄存器中?

我有一个8位像素数据的结构: struct __attribute__((aligned(4))) pixels { char r; char g; char b; char a; } 我想使用SSE指令来计算这些像素上的某些东西(即Paeth变换)。 如何将这些像​​素作为32位无符号整数加载到SSE寄存器中?