c++ - SSE/NEON查表优化

标签 c++ optimization sse neon lookup-tables

我有以下查找和插值代码需要优化。 (尺寸为128的浮台) 它将与 Windows 上的 Intel 编译器、OSX 上的 GCC 以及 neon OSX 上的 GCC 一起使用。

for(unsigned int i = 0 ; i < 4 ; i++)
{
    const int iIdx = (int)m_fIndex[i];
    const float frac = m_fIndex - iIdx;
    m_fResult[i] = sftable[iIdx].val + sftable[iIdx].val2 * frac;
}

我用 sse/neon 对所有内容进行了 vecorized。 (宏转换为 sse/neon 指令)

VEC_INT iIdx = VEC_FLOAT2INT(m_fIndex);
VEC_FLOAT frac = VEC_SUB(m_fIndex ,VEC_INT2FLOAT(iIdx);
m_fResult[0] = sftable[iIdx[0]].val2;
m_fResult[1] = sftable[iIdx[1]].val2;
m_fResult[2] = sftable[iIdx[2]].val2;
m_fResult[3] = sftable[iIdx[3]].val2;
m_fResult=VEC_MUL( m_fResult,frac);
frac[0] = sftable[iIdx[0]].val1;
frac[1] = sftable[iIdx[1]].val1;
frac[2] = sftable[iIdx[2]].val1;
frac[3] = sftable[iIdx[3]].val1;
m_fResult=VEC_ADD( m_fResult,frac);

我认为表访问和移入对齐内存是这里真正的瓶颈。 我不擅长汇编,但有很多 unpcklps 和 mov:

10026751  mov         eax,dword ptr [esp+4270h] 
10026758  movaps      xmm3,xmmword ptr [eax+16640h] 
1002675F  cvttps2dq   xmm5,xmm3 
10026763  cvtdq2ps    xmm4,xmm5 
10026766  movd        edx,xmm5 
1002676A  movdqa      xmm6,xmm5 
1002676E  movdqa      xmm1,xmm5 
10026772  psrldq      xmm6,4 
10026777  movdqa      xmm2,xmm5 
1002677B  movd        ebx,xmm6 
1002677F  subps       xmm3,xmm4 
10026782  psrldq      xmm1,8 
10026787  movd        edi,xmm1 
1002678B  psrldq      xmm2,0Ch 
10026790  movdqa      xmmword ptr [esp+4F40h],xmm5 
10026799  mov         ecx,dword ptr [eax+edx*8+10CF4h] 
100267A0  movss       xmm0,dword ptr [eax+edx*8+10CF4h] 
100267A9  mov         dword ptr [eax+166B0h],ecx 
100267AF  movd        ecx,xmm2 
100267B3  mov         esi,dword ptr [eax+ebx*8+10CF4h] 
100267BA  movss       xmm4,dword ptr [eax+ebx*8+10CF4h] 
100267C3  mov         dword ptr [eax+166B4h],esi 
100267C9  mov         edx,dword ptr [eax+edi*8+10CF4h] 
100267D0  movss       xmm7,dword ptr [eax+edi*8+10CF4h] 
100267D9  mov         dword ptr [eax+166B8h],edx 
100267DF  movss       xmm1,dword ptr [eax+ecx*8+10CF4h] 
100267E8  unpcklps    xmm0,xmm7 
100267EB  unpcklps    xmm4,xmm1 
100267EE  unpcklps    xmm0,xmm4 
100267F1  mulps       xmm0,xmm3 
100267F4  movaps      xmmword ptr [eax+166B0h],xmm0 
100267FB  mov         ebx,dword ptr [esp+4F40h] 
10026802  mov         edi,dword ptr [esp+4F44h] 
10026809  mov         ecx,dword ptr [esp+4F48h] 
10026810  mov         esi,dword ptr [esp+4F4Ch] 
10026817  movss       xmm2,dword ptr [eax+ebx*8+10CF0h] 
10026820  movss       xmm5,dword ptr [eax+edi*8+10CF0h] 
10026829  movss       xmm3,dword ptr [eax+ecx*8+10CF0h] 
10026832  movss       xmm6,dword ptr [eax+esi*8+10CF0h] 
1002683B  unpcklps    xmm2,xmm3 
1002683E  unpcklps    xmm5,xmm6 
10026841  unpcklps    xmm2,xmm5 
10026844  mulps       xmm2,xmm0 
10026847  movaps      xmmword ptr [eax+166B0h],xmm2

在分析时,win 上的 sse 版本没有太多好处。

您对如何改进有什么建议吗? neon/gcc 会产生任何副作用吗?

目前我考虑只对第一部分进行向量化,并在循环中进行表读取和插值,希望它能从编译器优化中受益。

最佳答案

操作系统?那么就和NEON没有关系了。

顺便说一句,NEON 无论如何都无法处理这么大的 LUT。 (我不了解上交所的情况)

首先验证 SSE 是否可以处理这种大小的 LUT,如果可以,我建议使用不同的编译器,因为 GCC 倾向于从内部函数中生成 intrinsucks。

关于c++ - SSE/NEON查表优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17724678/

相关文章:

c++ - 反向双向链表

c++ - C++ 中的 Blob 检测

c++ - 使用 AVX 指令实现 _mm256_permutevar8x32_ps

c++ - _mm_max_ss 在 clang 和 gcc 之间有不同的行为

c++ - 跨AVX channel 进行改组的最佳方法?

c++ - 在里面。静态成员,而 COPY CTOR 是私有(private)的

c++ - 调用虚函数的逻辑不清晰(或者是方法隐藏?)

algorithm - 旅行的最短路径

c++ - 您通常如何设置编译器的优化设置?

c# - 有什么方法可以优化这个 LINQ to Entities 查询吗?