gpt4 book ai didi

c++ - 写入内存缓冲区时的性能损失 (C++)

转载 作者:行者123 更新时间:2023-11-28 00:19:26 24 4
gpt4 key购买 nike

我正在编写一个小型渲染器(基于光栅化算法)。这是我正在做的一个个人项目,用于测试不同的技术。我正在测量渲染一堆三角形所花费的时间,在这样做时我注意到了一些奇怪的事情。该程序所做的是,如果给定像素与 2D 三角形重叠并通过一些其他测试(它在缓冲区中写入该三角形的颜色),则将其写入图像缓冲区(Vec3ui 的一维数组)。

Vec3<unsigned char> *fb = new Vec3<unsigned char>[w * h];
...
void rasterize(
...,
Vec3<unsigned char> *&fb,
float *&zbuffer)
{
Vec3<unsigned char> randcol(drand48() * 255, drand48() * 255, drand48() * 255);
...
uint32_t x, y;
// loop over bounding box of triangle
// check if given pixel is in triangle
for (y = ymin, p.y = ymin; y <= ymax; ++y, ++p.y)
{
for (x = xmin, p.x = xmin; x <= xmax; ++x, ++p.x)
{
if (pixelOverTriangle(...) {
fb[y * w + x] = randcol;
}
}
}
}

在我测量统计数据的地方,我认为在渲染三角形、进行所有测试等过程中实际花费的时间最长。碰巧当我使用给定数量的三角形运行程序时,我得到以下渲染时间:

74 ms

但是当我注释掉写入图像缓冲区的行时,我得到:

5 ms

明确地说,我这样做:

if (pixelOverTriangle(...) {
// fb[y * w + x] = randcol;
}

事实上,超过 90% 的时间都花在了写入图像缓冲区上!

我不得不说我尝试优化用于访问数组中元素的索引的计算方式,但这不是时间流逝的地方。时间进入实际将变量复制到缓冲区的右边(无论如何看起来)。

我对这些数字感到非常惊讶。

所以我有几个问题:

  • 是否符合预期?
  • 我做错了什么吗?
  • 我可以让它变得更好吗?我可以使用什么技术来优化它?

最佳答案

内存读/写比 C++ 看起来要多得多。通常情况下,您的处理器会缓存内存块以便快速访问;这极大地提高了连续内存中数据的性能:例如数组、结构和堆栈。但是,在尝试访问尚未缓存的内存(缓存未命中)时,处理器必须缓存一个新的内存块,这需要更长的时间(几分钟甚至几小时扩展到秒长周期)。通过访问长内存块的任意段(例如您的图像),您实际上可以保证连续的缓存未命中。

更糟糕的是,计算机内存 (RAM) 实际上位于虚拟页面上,这些页面一直在物理内存中换入和换出。如果你的图像足够大,可以跨越多个内存页(通常每个大约 4kb),那么你的操作系统实际上是从辅助存储(你的硬盘驱动器)加载和卸载数据,你可以想象这比直接从内存读取花费的时间要长得多.

我找到了 an article来自另一个关于缓存性能的 stackoverflow 问题,它可能比我更好地回答你的问题。确实,重要的是要了解内存读/写实际上在做什么,以及它如何显着影响性能。

关于c++ - 写入内存缓冲区时的性能损失 (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28286308/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com