随机访问缓冲区优化

random access to buffer optimisation

本文关键字:优化 缓冲区 访问 随机      更新时间:2023-10-16

我有colorBuffer Color[width*height](最可能是800*600)

在栅格化过程中我调用:

void setPixel(int x, int y, Color & color)
{
    colorBuffer[y * width + x] = color;
}

事实证明,这种对颜色缓冲区的随机访问是非常无效的,并且减慢了应用程序的速度。

我认为这是我使用它的方式造成的。我计算一些像素(与光栅化算法),并调用setPixel。
所以我认为我的缓冲区不在缓存中,这是主要问题。当试图一次写入整个缓冲区时,它要快得多。

有没有办法,如何优化这个?

编辑

我不使用它来用两个for循环填充缓冲区。
我用它来绘制"随机"像素。
例如,当光栅化线时,我使用

setPixel(10,10);
calculate next point
setPixel(10,11);
calculate next point
setPixel(next point)
...

在我看来,缓冲区的访问模式取决于你的算法处理像素的顺序。您能不能简单地更改这个顺序,以便创建对缓冲区的顺序访问方案?

是的,你应该尝试缓存友好,但我要做的第一件事是找出是什么在花费时间。

这很简单。只要暂停几次,看看它在做什么。

如果它主要在calculate next point中,你应该看到它在那里做什么,因为那是时间的去向。(我假设你明白这里的"in"是指"在堆栈上"。)

如果它主要在SetPixel中,当您暂停它时,请查看拆卸窗口。

如果它在例程的序言/尾声中花费了很多时间,它应该被内联。

如果它在实际移动指令到colorBuffer中花费了很多时间,那么您就遇到了缓存问题。

如果在索引计算y * width + x的代码中花费了很多时间,那么你可能想看看是否可以使用一个初始化的指针。

如果你修复了任何东西,你应该重新做一遍,因为你可能发现了另一个进一步加速的机会。

首先要注意的是,处理像素的方式会对速度产生巨大影响。如果你这样做

for (int x = 0; x < width;++x)
{
  for (int y = 0; y < height; ++y)
  {
    setPixel(x,y,Color());
  }
}

这将对性能非常不利,因为您实际上是在内存宽度方向上跳转(注意您执行的是y*width + x)。

如果将处理顺序更改为

for (int y = 0; y < height;++y)
{
  for (int x = 0; x < width; ++x)
  {
    setPixel(x,y,Color());
  }
}

您应该已经注意到性能的提高,因为处理器现在有机会缓存内存访问(以前没有)。

此外,在实际设置内存之前,您应该检查是否可以确定整个像素块具有相同的颜色值。然后你可以将这些固定的颜色值按块复制到你的图像数组中,这也可以为你节省大量的性能。