【问题标题】:SSE Intrinsics - Logical NOT OptimizationSSE Intrinsics - 逻辑非优化
【发布时间】:2016-09-11 21:26:48
【问题描述】:

我正在使用 SSE 对图像中的像素执行按位非运算。

我有一些问题:

  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++;
}

【问题讨论】:

  • 你试过循环展开吗?
  • 您是否从自动矢量化中获得了不错的结果?我猜a[i] = ~a[i] 会很好地自动矢量化。将其编写为全一的 XOR(即~0ULL)也可能会有所帮助,尤其是。如果您的目标是 AVX。 (VPANDN 反转寄存器操作数,而不是寄存器/内存操作数)。您的目标是 AVX,还是仅限 SSE2 版本? AVX 可以使用 256b FP 布尔运算,这没关系,因为无论如何您只能维持每个时钟吞吐量一个向量,因为您将结果存储回内存。您正在针对哪些微架构进行调整,您正在对哪些微架构进行基准测试?
  • 为什么要更改舍入模式?您的代码不会执行任何 FP 操作,除非 SrcImage1.SembufGetHeight() 返回 floatdouble
  • 79 毫秒似乎很高,除非您的图像很大,或者您忘记打开编译器优化,或者您使用的是 20 年的计算机?
  • 对于少量迭代,OpenMP 开销将太大,对于大尺寸,操作受内存带宽限制。这并不一定意味着您不会看到使用线程的大尺寸没有任何好处,但它肯定不会随着单个套接字系统上的线程数量而扩展。如果尺寸介于 L2 和 L3 之间,您可能会看到一些合适的。

标签: c++ performance openmp sse simd


【解决方案1】:
  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. 我在您提供的 sn-p 中没有看到任何瓶颈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-21
    • 2012-08-10
    • 2016-06-25
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    相关资源
    最近更新 更多