SSE指令集-逻辑非优化

3

我正在使用SSE对图像中的像素执行按位NOT操作。

我有一些问题:

  1. 是否可以使用OpenMP进一步优化?
  2. 我的算法中是否存在可以优化的瓶颈?

以下是我的代码:

unsigned int iSSE2Size = (SrcImage1.GetHeight() * (SrcImage1.GetStepBytes() >> 1)) >> 3;
__m128i *m_ucSrcPtr = (__m128i *)SrcImage1.GetWordPtr();
__m128i *m_ucDstPtr = (__m128i *)DestImage.GetWordPtr();
__m128i iMaxVal = _mm_set1_epi16(0xFFFF); 
unsigned short *srcRowPtr, *dstRowPtr;
while (iSSE2Size-- > 0)
{
    *m_ucDstPtr = _mm_andnot_si128(*m_ucSrcPtr, iMaxVal );
    m_ucSrcPtr++;
    m_ucDstPtr++;
}

1
你尝试过循环展开吗? - user541686
2
你的自动向量化结果还不错吗?我猜 a[i] = ~a[i] 可以很好地进行自动向量化。将其写成与全1异或(即 ~0ULL)可能也有帮助,特别是如果你的目标是 AVX。(VPANDN 反转寄存器操作数,而不是寄存器/内存操作数)。你是针对 AVX 还是 SSE2-only 版本?AVX 可以使用 256b FP 布尔运算,这很好,因为你每个时钟周期只能维持一个向量,因为你正在将结果存回内存。你正在调整哪些微架构,并在哪些微架构上进行基准测试? - Peter Cordes
2
你为什么要改变舍入模式?除非SrcImage1.SembufGetHeight()返回一个floatdouble,否则你的代码不会执行任何FP操作。 - Peter Cordes
2
79毫秒似乎非常高,除非你的图像非常大,或者你忘记打开编译器优化,或者你正在使用20年前的电脑? - Paul R
2
对于迭代次数较少的情况,OpenMP 的开销会过大;而对于较大的数据规模,操作会受到内存带宽的限制。这并不一定意味着在使用线程处理大规模数据时无法获得优势,但它肯定不能随着单个插槽系统上线程数量的增加而扩展。如果大小介于 L2 和 L3 之间,则可能会产生一些好处。 - Z boson
显示剩余10条评论
1个回答

0
  1. 你可以尝试同时使用循环展开和OpenMP来优化你的代码。

    #pragma omp parallel for
    for (;iSSE2Size-=2 > 0;)
    {
        *m_ucDstPtr = _mm_andnot_si128(*m_ucSrcPtr, iMaxVal );
        m_ucSrcPtr++;
        m_ucDstPtr++;
    
        *m_ucDstPtr = _mm_andnot_si128(*m_ucSrcPtr, iMaxVal );
        m_ucSrcPtr++;
        m_ucDstPtr++;
    }
    

    请注意,您可能可以多次展开循环以提高性能。

  2. 我在您提供的片段中没有看到任何瓶颈。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接