C++ 随机访问缓冲区优化

C++ 随机访问缓冲区优化,c++,optimization,buffer,C++,Optimization,Buffer,我有颜色缓冲区颜色[宽度*高度](很可能是800*600) 在光栅化过程中,我调用: void setPixel(int x, int y, Color & color) { colorBuffer[y * width + x] = color; } 事实证明,这种对颜色缓冲区的随机访问实际上是无效的,会减慢我的应用程序的速度 我认为这是我使用它的方式造成的。我计算一些像素(使用光栅化算法)并调用setPixel。 所以我认为我的缓冲区不在缓存中,这是主要问题。当试图一次写入整

我有
颜色缓冲区颜色[宽度*高度]
(很可能是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)
...

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

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

for (int x = 0; x < width;++x)
{
  for (int y = 0; y < height; ++y)
  {
    setPixel(x,y,Color());
  }
}
for(int x=0;x
这对性能非常不利,因为您实际上是在内存宽度方向上跳跃(请注意,您执行的是y*width+x)

如果您只是将处理顺序更改为

for (int y = 0; y < height;++y)
{
  for (int x = 0; x < width; ++x)
  {
    setPixel(x,y,Color());
  }
}
for(int y=0;y
您应该已经注意到了性能的提高,因为处理器现在有机会缓存内存访问(以前没有)


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

是的,您应该尽量做到缓存友好, 但我要做的第一件事是找出什么需要时间

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

如果它主要在
计算下一个点
,你应该看到它在那里做什么,因为这就是时间的方向。 (我想你理解“in”是指“在堆栈上”。)

如果它主要在
SetPixel
中,当您暂停它时,请查看反汇编窗口

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

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

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


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

@relaxx我想你是在循环中计算对象吧?与其为每种颜色确定位置,不如用两个嵌套的循环扫描缓冲区,然后为每个像素位置确定颜色,这样效率会更高。我不能这样做。用户可以像
setColor
paintCircle
一样使用它,然后再使用另一个
setColor
printLine
。我计算圆点,并用实际颜色书写它们。然后计算线点并使用新的实际颜色计算它们。我真的看不到路,怎么填充颜色缓冲区afterwards@relaxxx你可以。这就是光栅化器的工作原理。请参阅示例:,至少,您能按从上到下、从左到右的顺序对要光栅化的对象进行排序,然后对每个在同一方向工作的对象进行光栅化吗?@没用,我不能。我一得到它们就必须光栅化。为什么只要在下一次显示刷新、保存到文件或其他任何操作之前完成所有操作,您是否“急切地”(即,一旦调用)光栅化就很重要?如果是这样的话,您所能做的就是尝试内联
setPixel
,并尝试使
Color
对象尽可能小。将其内联也可能会让事情慢一点谢谢。这是缓存问题。主要的问题是如何使它更快。可能是强制缓冲区留在缓存中或类似的东西