c++ - 为什么我的 SSE 不比 C/C++ 代码快?

标签 c++ opencv sse

我刚开始使用 SSE 优化我的计算机视觉项目代码,旨在检测图像中的肤色。下面是我的功能。该函数获取彩色图像并查看每个像素并返回概率图。注释掉的代码是我原来的 C++ 实现,其余的是 SSE 版本。我对它们都进行了计时,发现 SSE 并不比我原来的 C++ 代码快多少,这很奇怪。关于正在发生的事情或如何进一步优化功能的任何建议?

void EvalSkinProb(const Mat& cvmColorImg, Mat& cvmProb)
{
    std::clock_t ts = std::clock();  
    Mat cvmHSV = Mat::zeros(cvmColorImg.rows, cvmColorImg.cols, CV_8UC3);
    cvtColor(cvmColorImg, cvmHSV, CV_BGR2HSV);
    std::clock_t te1 = std::clock(); 

    float fFG, fBG;
    double dp;

    __declspec(align(16)) int frgb[4] = {0};
    __declspec(align(16)) int fBase[4] = {g_iLowHue, g_iLowSat, g_iLowVal, 0};
    __declspec(align(16)) int fIndx[4] = {0};
    __m128i* pSrc1 = (__m128i*) frgb;
    __m128i* pSrc2 = (__m128i*) fBase;
    __m128i* pDest = (__m128i*) fIndx;
    __m128i m1;

    for (int y = 0; y < cvmColorImg.rows; y++)
    {
        for (int x = 0; x < cvmColorImg.cols; x++)
        {
            cv::Vec3b hsv = cvmHSV.at<cv::Vec3b>(y, x);
            frgb[0] = hsv[0];hsv[1] = hsv[1];hsv[2] =hsv[2];
            m1 = _mm_sub_epi32(*pSrc1, *pSrc2);
            *pDest = _mm_srli_epi32(m1, g_iSValPerbinBit); 

            // c++ code
            //fIndx[0] = ((hsv[0]-g_iLowHue)>>g_iSValPerbinBit);
            //fIndx[1] = ((hsv[1]-g_iLowSat)>>g_iSValPerbinBit);
            //fIndx[2] = ((hsv[2]-g_iLowVal)>>g_iSValPerbinBit);

            fFG = m_cvmSkinHist.at<float>(fIndx[0], fIndx[1], fIndx[2]);
            fBG = m_cvmBGHist.at<float>(fIndx[0], fIndx[1], fIndx[2]);
            dp = (double)fFG/(fBG+fFG);
            cvmProb.at<double>(y, x) = dp;          
        }
    }
    std::clock_t te2 = std::clock();  
    double dSecs1 = (double)(te1-ts)/(CLOCKS_PER_SEC);
    double dSecs2 = (double)(te2-te1)/(CLOCKS_PER_SEC);
}

最佳答案

这里的第一个问题是您对大量数据移动所做的 SSE 工作很少。您将花费大部分时间为 2 条指令打包/解包 SSE 寄存器中的数据...

其次,此代码中会出现非常微妙的性能损失。

您正在使用缓冲区在变量和 SSE 寄存器之间传输数据。这是一个大禁忌

原因在于 CPU 加载/存储单元。当您将数据写入内存位置,然后立即尝试以不同的字大小将其读回时,通常会强制将数据一直刷新到缓存并重新读取。这可能会招致 20 多个周期的惩罚。

这是因为 CPU 加载/存储单元没有针对这种异常访问进行优化。

关于c++ - 为什么我的 SSE 不比 C/C++ 代码快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8149132/

相关文章:

c++ - 如何在二维数组 (C++) 中检查我周围单元格的邻居?

c - 在 OpenCV 中读取 AVI 文件时出现未知错误

cuda - 将 SSE/AVX 单元与 GPU 核心进行比较公平吗?

c++ - 为什么模板只能在头文件中实现?

c++ - 随对象在OpenGL中移动而改变旋转点?

C++:reinterpret_cast 是这些场景中的最佳选择吗?

OpenCv 安装问题。不满意的链接错误 java

android - NDK - GNUSTL 从 NDK(修订版 r18)中删除后出现的问题

c++ - 追踪哪个依赖项包含 SSE 指令

c++ - 为什么在实践中向右移动在 Neon 和 SSE 中向左移动(反之亦然)?