performance - 图形:浮点累积图像的最佳性能

标签 performance optimization opengl graphics

我需要加快我正在处理的一些粒子系统的视觉效果。令人眼前一亮的是添加混合、积累以及粒子上的轨迹和发光。目前我正在手动渲染到浮点图像缓冲区,在最后一分钟转换为无符号字符,然后上传到 OpenGL 纹理。为了模拟辉光,我以不同的分辨率和不同的偏移多次渲染相同的纹理。这被证明太慢了,所以我正在考虑改变一些东西。问题是,我的开发硬件是 Intel GMA950,但目标机器有 Nvidia GeForce 8800,所以在这个阶段很难分析 OpenGL 的东西。

我做了一些非常不科学的分析,发现大部分速度减慢来自处理浮点图像:按常数缩放所有像素以淡出它们,并将浮点图像转换为无符号字符并上传到图形硬件。因此,我正在寻找以下优化选项:

  • 在定点 16.16 配置中用 uint32 替换 float
  • 使用 SSE2 程序集优化浮点运算(图像缓冲区是一个 1024*768*3 的 float 组)
  • 使用 OpenGL 累积缓冲区而不是 float 组
  • 使用 OpenGL 浮点 FBO 而不是 float 组
  • 使用 OpenGL 像素/顶点着色器

您有任何这些可能性的经验吗?有什么想法,建议吗?还有什么我没想到的?

最佳答案

问题只是您必须处理的数据量太大。

您的 float 缓冲区大小为 9 兆字节,并且您不止一次接触数据。您的渲染循环很可能看起来像这样:

  • 清除缓冲区
  • 在上面渲染一些东西(使用读写)
  • 转换为无符号字节
  • 上传到 OpenGL

您需要移动大量数据,而缓存对您帮助不大,因为图像比您的缓存大得多。假设您触摸每个像素五次。如果是这样,您将 45mb 的数据移入和移出慢速主内存。 45mb 听起来不是很多数据,但考虑到几乎每次内存访问都会导致缓存未命中。 CPU 将花费大部分时间等待数据到达。

如果您想留在 CPU 上进行渲染,您无能为力。一些想法:

  • 将 SSE 用于非临时加载和存储可能会有所帮助,但它们会使您的任务变得相当复杂(您必须对齐读取和写入)。

    <
  • 尝试将渲染分解成多个图 block 。例如。在较小的矩形(256*256 左右)上做所有事情。这背后的想法是,您实际上可以从缓存中获益。例如,在清除矩形后,整个位图将在缓存中。渲染和转换为字节现在会快很多,因为不再需要从相对较慢的主内存中获取数据。

  • 不得已:降低粒子效果的分辨率。这将以视觉质量为代价让您物有所值。

最好的解决办法是将渲染图移到显卡上。如今,渲染到纹理功能已成为标准。让它与 OpenGL 一起工作有点棘手,因为你必须决定使用哪个扩展,但一旦你让它工作,性能就不再是问题了。

顺便说一句 - 你真的需要浮点渲染目标吗?如果你摆脱每个像素 3 个字节,你会看到一个很好的性能改进。

关于performance - 图形:浮点累积图像的最佳性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/590504/

相关文章:

java - 网络流量 : Adding a new edge

php - 在数据映射器模式中,是否值得跟踪哪些字段发生了变化?

python - Numpy 数组 : Efficient use of arrays containing indices

google-chrome - 导出 PageSpeed Insights (by Google) 结果

algorithm - 最佳订单履行

performance - 优化 GPU 利用率处理离散图像的技术

arrays - 在数组中查找具有最多相同字母数的字符串对

java - 如何提高包裹在 ThreadLocal 中的 SimpleDateFormat 的性能?

c++ - 每个网格多个顶点缓冲区

opengl - 是否必须为几何着色器中发出的每个顶点设置每个变量?