随机访问缓冲区优化
random access to buffer optimisation
我有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());
}
}
您应该已经注意到性能的提高,因为处理器现在有机会缓存内存访问(以前没有)。
此外,在实际设置内存之前,您应该检查是否可以确定整个像素块具有相同的颜色值。然后你可以将这些固定的颜色值按块复制到你的图像数组中,这也可以为你节省大量的性能。
- C++字符*缓冲区的大小
- 空基优化子对象的地址
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 关闭||运算符优化
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- Xaudio2在更改缓冲区或循环时弹出声音
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 优化图像缓冲区
- 从本机C++结构构建时,是否可以优化平面缓冲区序列化
- 别名,用于使用 std::aligned_union 和 std::aligned_union 进行小型缓冲区优化
- 如何通过玩缓冲区大小来优化读写
- 协议缓冲区 GetRepeatedField (反射) 代码优化
- 实现任意类型擦除的小缓冲区优化的简单方法(如std::function.)
- 随机访问缓冲区优化
- 缓冲区溢出在某些地方只有在编译器优化打开
- 优化内存和性能的传输数据缓冲区