RGB32字节数组内存访问优化

时间:2014-04-28 05:13:19

标签: c++ memory optimization directshow rgb

我对低级内存优化知之甚少,但我试图弄清楚如何从保存rbg32数据的unsigned char数组优化内存访问。

我正在构建一个需要平均数据区域的directshow变换滤镜(CTransInPlaceFilter)。提供给我的数据是rgb32格式(B G R 0xFF B G R 0xFF B G R 0xFF etc)。我正在循环数据并计算平均红色,绿色和蓝色通道。

我发现当我取消引用字节数组中的数据时,视频播放运行CPU并且没有和访问,CPU没有那么多工作。

在阅读了大量帖子后,我认为这是CPU带宽瓶颈的记忆。

以下是转换函数的代码:

  

HRESULT CFilter :: Transform(IMediaSample * pSample){

BYTE* data = NULL;
pSample->GetPointer(&data);

if (mVideoType == MEDIASUBTYPE_RGB32) {
    Rect roi(0, 0, 400, 400);           // Normally this is dynamic
    int totalPixels = roi.width * roi.height;

    // Find the average color
    unsigned int totalR = 0, totalG = 0, totalB = 0;
    for (int r = 0; r < roi.height; r++) {
        int y = roi.y + r;
        BYTE* pixel = data + (roi.x + y * mWidth) * 4;      // 4 bytes per pixel

        for (int c = 0; c < roi.width; c++) {
            totalB += *pixel;           // THESE 3 LINES IS THE ISSUE
            totalG += *(++pixel);
            totalR += *(++pixel);
            pixel++;
        }
    }
    int meanR = (int)floor(totalR / totalPixels);
    int meanG = (int)floor(totalG / totalPixels);
    int meanB = (int)floor(totalB / totalPixels);
    // Does work with the averaged data
}
return S_OK; }

因此,当我在没有3个解除引用线的情况下运行视频时,我获得了大约10-14%的cpu使用率。通过这些线路,我可以获得30-34%的CPU使用率。

我还尝试将数据复制到缓冲区以访问数据。

mempy(mData, data, mWidth * mHeight * 4);      // mData is only allocated once in constructor
...
totalB += mData[x + y * mWidth];

cpu使用率变为22-25%。

是否可以将CPU使用率再次降低到接近10?以某种方式更快地访问数据?我应该尝试使用asm吗?

其他信息:视频为10bit 1280 X 720,使用GraphEdit测试我的过滤器。 我的过滤器不会更改源图像(因此它不会复制)。 如果有帮助,我可以解决这个过程。

提前致谢!

修改

有关详细信息,我添加了directshow图表。视频是10位,但Lav滤镜将RGB32(8位)传递给我。它是调试版本,会释放它的速度(最终我将编译为发布版本)。

enter image description here

我运行了两种不同的方式(前面提到过)并对它们的经过时间进行了基准测试。通过解除引用,每次转换运行时我会得到0.126208毫秒。如果没有解除引用,我会得到0.009毫秒。

我还尝试通过

来减少循环
for (int c = 0; c < roi.width; c += 4) {
    totalB += pixel[c] + pixel[c + 3] + pixel[c + 6] + pixel[c + 9];
    totalG += pixel[c + 1] + pixel[c + 4] + pixel[c + 7] + pixel[c + 10];
    totalR += pixel[c + 2] + pixel[c + 5] + pixel[c + 8] + pixel[c + 11];
}

这没有改变CPU使用率,经过的时间仍然在0.12左右

编辑2:

我还在发布中构建了所有依赖项和项目本身,并得到了相同的结果。访问速度仍然很慢。

1 个答案:

答案 0 :(得分:1)

我解决了这个问题。所以问题是数据是指向视频内存中数据的指针。我试图使用数据并将其从视频传输到计算机RAM,从而导致内存带宽错误。立即复制所有数据(memcpy)更快但仍然很慢。相反,我必须使用特定的英特尔SSE4命令有效地将数据从视频内存复制到计算机内存。

我使用了this file(gpu_memcpy)。它包含与memcpy类似的功能,但使用GPU来完成工作。它速度更快,复制后,访问数据的速度很快。