相关疑难解决方法(0)

访问打包在128位寄存器中的任意16位元素

使用英特尔编译器内在函数,给定一个128位寄存器,打包8个16位元素,如何从寄存器中访问(廉价)任意元素,以便后续使用_mm_cvtepi8_epi64(符号扩展两个8位元素,打包在较低位置) 16位寄存器,两个64位元素)?


我会解释为什么我问:

  1. 输入:具有k个字节的内存缓冲区,每个字节为0x0或0xff.
  2. 期望输出:对于输入的每两个连续字节,寄存器分别用0x0和包装两个四字(64位)0xffff ffff ffff ffff.
  3. 最终目标:根据输入缓冲区的条目对k个双精度缓冲区进行求和.

注意:输入缓冲区的值0x0和值0xff可以更改为最有用的值,前提是在总和之前屏蔽效果仍然存在.

从我的问题可以明显看出,我目前的计划如下,在输入缓冲区中流式传输:

  1. 将输入掩码缓冲区从8位扩展到64位.
  2. 使用扩展掩码屏蔽双打缓冲区.
  3. 总结蒙面的双打.

谢谢,阿萨夫

assembly sse simd intrinsics micro-optimization

7
推荐指数
1
解决办法
787
查看次数

__m128中至少有4个SP值

假设有一个__m128变量包含4个SP值,并且您想要最小值,是否有任何可用的内部函数,或者除了值之间的天真线性比较之外的任何其他函数?

正确知道我的解决方案如下(假设输入__m128变量是x):

x = _mm_min_ps(x, (__m128)_mm_srli_si128((__m128i)x, 4));
min = _mm_min_ss(x, (__m128)_mm_srli_si128((__m128i)x, 8))[0];
Run Code Online (Sandbox Code Playgroud)

这是非常可怕的,但它的工作(顺便说一下,有什么类似的_mm_srli_si128但是__m128类型?)

c sse simd

7
推荐指数
1
解决办法
768
查看次数

SSE:将__m128转换为float

我有以下C代码:

__m128 pSrc1 = _mm_set1_ps(4.0f);
__m128 pDest;
int i;
for (i=0;i<100;i++) {
       m1 = _mm_mul_ps(pSrc1, pSrc1);      
       m2 = _mm_mul_ps(pSrc1, pSrc1);        
       m3 = _mm_add_ps(m1, m2);             
       pDest = _mm_add_ps(m3, m3); 
}

float *arrq = (float*) pDest;
Run Code Online (Sandbox Code Playgroud)

直到for循环结束的所有内容都有效.我现在要做的是将__m128类型转换回float.因为它存储了4个浮点数,我认为我很容易将其转换为浮动*.我究竟做错了什么?(这是一个测试代码,所以不要怀疑).我基本上尝试了所有可能的转换.谢谢你的帮助.

c c++ sse

6
推荐指数
1
解决办法
1万
查看次数

使用 __m512 (AVX512) 水平添加

如何使用 512 位 AVX 寄存器中的浮点数有效地执行水平加法(即将单个向量中的项加在一起)?对于 128 和 256 位寄存器,这可以使用 _mm_hadd_ps 和 _mm256_hadd_ps 来完成,但没有 _mm512_hadd_ps。Intel 内在函数指南文档 _mm512_reduce_add_ps。它实际上并不对应于单个指令,但它的存在表明存在一种最佳方法,但它似乎没有在 GCC 最新快照附带的头文件中定义,我找不到它与谷歌。

我认为可以使用 _mm512_shuffle_ps 和 _mm512_add_ps 模拟“hadd”,或者我可以使用 _mm512_extractf32x4_ps 将 512 位寄存器分解为四个 128 位寄存器,但我想确保我不会错过更好的东西。

simd intrinsics avx512

6
推荐指数
1
解决办法
5471
查看次数

用sse累积整数向量

我试图改变这个代码来处理std::vector<int>.

float accumulate(const std::vector<float>& v)
{
 // copy the length of v and a pointer to the data onto the local stack
 const size_t N = v.size();
 const float* p = (N > 0) ? &v.front() : NULL;

 __m128 mmSum = _mm_setzero_ps();
 size_t i = 0;

 // unrolled loop that adds up 4 elements at a time
 for(; i < ROUND_DOWN(N, 4); i+=4)
 {
  mmSum = _mm_add_ps(mmSum, _mm_loadu_ps(p + i));
 }

 // add up single values until all …
Run Code Online (Sandbox Code Playgroud)

c++ x86 sse vector simd

6
推荐指数
2
解决办法
2493
查看次数

如何将XMM 128位寄存器拆分为两个64位整数寄存器?

如何将128位xmm寄存器拆分为两个64位quadwords?

我输入的字数非常多xmm1,想要将较高的四字r9和较低的四字输入r10,或RAXRDX

movlpdmovhpd仅与reg到mem兼容,反之亦然。

x86 assembly sse

6
推荐指数
1
解决办法
1180
查看次数

使用SSE/AVX获取存储在__m256d中的值的总和

有没有办法获得存储在__m256d变量中的值的总和?我有这个代码.

acc = _mm256_add_pd(acc, _mm256_mul_pd(row, vec));
//acc in this point contains {2.0, 8.0, 18.0, 32.0}
acc = _mm256_hadd_pd(acc, acc);
result[i] = ((double*)&acc)[0] + ((double*)&acc)[2];
Run Code Online (Sandbox Code Playgroud)

此代码有效,但我想用SSE/AVX指令替换它.

c++ optimization sse avx avx2

6
推荐指数
2
解决办法
1690
查看次数

C#中的硬件SIMD解析性能提升

我已经实现了一种使用 .NET 中可用的 SIMD 内在函数解析长度 <= 8 的无符号整数字符串的方法,如下所示:

public unsafe static uint ParseUint(string text)
{
  fixed (char* c = text)
  {
    var parsed = Sse3.LoadDquVector128((byte*) c);
    var shift = (8 - text.Length) * 2;
    var shifted = Sse2.ShiftLeftLogical128BitLane(parsed, 
      (byte) (shift));

    Vector128<byte> digit0 = Vector128.Create((byte) '0');
    var reduced = Sse2.SubtractSaturate(shifted, digit0);

    var shortMult = Vector128.Create(10, 1, 10, 1, 10, 1, 10, 1);
    var collapsed2 = Sse2.MultiplyAddAdjacent(reduced.As<byte, short>(), shortMult);

    var repack = Sse41.PackUnsignedSaturate(collapsed2, collapsed2);
    var intMult = Vector128.Create((short)0, 0, 0, 0, 100, …
Run Code Online (Sandbox Code Playgroud)

c# sse simd avx system.numerics

6
推荐指数
3
解决办法
417
查看次数

使用 NumPy 对 uint16 与 uint64 数组求和时没有加速吗?

我必须对相对较小的整数进行大量操作(加法),并且我开始考虑哪种数据类型在 64 位机器上能提供最佳性能。

\n

我确信uint16将 4 加在一起所需的时间与 1 相同uint64,因为 ALU 可以uint16仅使用 1 个uint64加法器进行 4 次加法。(进位传播意味着这对于单个 64 位加法器来说并不容易,但这就是整数 SIMD 指令的工作原理。)

\n

显然情况并非如此:

\n
In [3]: data = np.random.rand(10000)\n\nIn [4]: int16 = data.astype(np.uint16)\n\nIn [5]: int64 = data.astype(np.uint64)\n\nIn [6]: int32 = data.astype(np.uint32)\n\nIn [7]: float32 = data.astype(np.float32)\n\nIn [8]: float64 = data.astype(np.float64)\n\nIn [9]: %timeit int16.sum()\n13.4 \xc2\xb5s \xc2\xb1 43.3 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n\nIn [10]: %timeit int32.sum()\n13.9 \xc2\xb5s \xc2\xb1 347 …
Run Code Online (Sandbox Code Playgroud)

python performance numpy simd compiler-optimization

6
推荐指数
1
解决办法
1217
查看次数

向Delphi ASM中的所有16个XMM插槽广播一个字节值

使用VBROADCASTS命令在AVX中很容易,如果值是double或float,则在SSE中很容易.

如何向Delphi ASM中的XMM寄存器中的每个插槽广播一个8位值?

delphi assembly sse delphi-7 basm

5
推荐指数
2
解决办法
663
查看次数