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

标签 c++ memory memory-management buffer

我正在编写一个小型渲染器(基于光栅化算法)。这是我正在做的一个个人项目,用于测试不同的技术。我正在测量渲染一堆三角形所花费的时间,在这样做时我注意到了一些奇怪的事情。该程序所做的是,如果给定像素与 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/

相关文章:

c++ - 什么是 C++ 中的代理类

macos - 使用 MMAP 读取时 OS X 上的页面错误

javascript - JS : Boolean Array vs Int8Array

c - GPU 上是否有内存保护

c - 编译器优化会影响动态内存分配吗?

c++ - clang 的 uint24_t 是如何工作的?我可以在 clang/LLVM 之外使用它吗?

c++ - 'new' 语句是否会在不抛出异常的情况下失败?

c++ - 为什么C语言的头文件中使用 '#'符号?为什么不是任何其他符号?

objective-c - iPad 的基于 ARC 的项目中内存不足访问崩溃报告

java - java 的 native 内存跟踪输出的 "other"部分有什么内容?