Tag: simd

SSE加载和添加

假设我有两个向量由两个double类型的数组表示,每个数组大小为2.我想添加相应的位置。 因此假设向量i0和i1 ,我想将i0[0] + i1[0]和i0[1] + i1[1]在一起。 由于类型是double ,我需要两个寄存器。 诀窍是将i0[0]和i1[0] ,以及i0[1]和i1[1]放在另一个中,只需添加寄存器即可。 我的问题是,如果我调用_mm_load_ps(i0[0])然后_mm_load_ps(i1[0]) ,它会将它们分别置于低位和高位64位,还是会用第二次load替换寄存器? 如何将两个双打放在同一个寄存器中,以便我可以在之后调用add_ps ? 谢谢,

gcc的__builtin_cpu_supports检查OS支持吗?

GCC编译器提供了一组内置函数来测试某些处理器function,例如某些指令集的可用性。 但是,根据这个线程,我们也可能知道操作系统可能无法启用某些cpufunction。 所以问题是: __builtin_cpu_supports intrinsics还检查操作系统是否启用了某些处理器function?

SSE优化代码执行类似于普通版本

我想采取英特尔SSE的第一步,所以我按照这里发布的指南,区别在于我不是为Windows和C ++开发,而是为Linux和C开发(因此我不使用任何_aligned_malloc而是posix_memalign )。 我还实现了一种计算密集型方法,而没有使用SSE扩展。 令人惊讶的是,当我运行程序时,两段代码(一台SSE和一台没有)需要花费相同的时间来运行,通常是使用SSE的时间略高于另一段。 这是正常的吗? GCC是否可能已经使用SSE优化(也使用-O0选项)? 我也尝试过-mfpmath=387选项,但没办法,仍然是一样的。

Websocket数据取消屏蔽/多字节xor

websocket规范将unmasking数据定义为 j = i MOD 4 transformed-octet-i = original-octet-i XOR masking-key-octet-j 其中mask是4个字节长,每个字节必须应用unmasking。 有没有办法更有效地做到这一点,而不仅仅是循环字节? 运行代码的服务器可以假定为Haswell CPU,OS是内核> 3.2的Linux,因此SSE等都存在。 编码是在C语言中完成的,但如果需要,我也可以执行asm。 我试图自己查找解决方案,但是无法弄清楚是否有任何SSE1-5 / AVE /中的任何一个都有适当的指令(无论多少扩展 – 多年来失去了很多轨道) 非常感谢你! 编辑:重新阅读规范几次之后,似乎它实际上只是用掩码字节对数据字节进行异或,我可以一次做8个字节,直到最后几个字节。 问题仍然存在,因为我认为可能仍然有一种方法可以使用SSE等来优化它(可能一次只处理16个字节?让进程执行for循环?…)

使用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()等。

如何初始化范围从0到N的SIMD向量?

我有以下函数我正在尝试编写一个AXV版本: void hashids_shuffle(char *str, size_t str_length, char *salt, size_t salt_length) { size_t i, j, v, p; char temp; if (!salt_length) { return; } for (i = str_length – 1, v = 0, p = 0; i > 0; –i, ++v) { v %= salt_length; p += salt[v]; j = (salt[v] + v + p) % […]

如何使用Neon SIMD将unsigned char转换为有符号整数

如何使用Neon将数据类型uint8_t的变量转换为int32_t ? 这样做我找不到任何内在的东西。

使用SIMD优化1D热方程

我正在使用CFD代码(用于计算流体动态)。 我最近有机会在我的一个循环中看到英特尔编译器使用SSE,在这个循环中为计算性能增加了近2倍的因子。 但是,使用SSE和SIMD指令似乎更像是运气。 大多数情况下,编译器什么都不做。 我正在尝试强制使用SSE,考虑到AVX指令将在不久的将来强化这一方面。 我做了一个简单的1D热转印代码。 它由两个阶段组成,使用另一个阶段的结果(U0 – > U1,然后是U1 – > U0,然后是U0 – > U1等)。 当它迭代时,它会收敛到稳定的解决方案。 主代码中的大部分循环都使用相同的计算方式。 (有限差分)。 但是,我的代码比普通循环慢两倍。 结果是相同的,因此计算是一致的。 我弄错了吗? 在使用Westmer进行测试之前,我正在使用Core 2来测试循环。 这是代码,带有SSE循环,然后是引用循环: #include #include #include //#include #define n1 1004 #define niter 200000 int i,j,t; double U0[n1] __attribute__ ((aligned(16))); double U1[n1] __attribute__ ((aligned(16))); double Dx,Dy,Lx,Ly,InvDxDx,Dt,alpha,totaltime,Stab,DtAlpha,DxDx; __m128d vmmx00; __m128d vmmx01; __m128d vmmx02; __m128d vmmx10; […]