【问题标题】:What kind of data rate can I expect with glTexImage2D?glTexImage2D 可以达到什么样的数据速率?
【发布时间】:2013-04-16 21:32:44
【问题描述】:

我正在使用 OpenGL 对图像进行调整,所以我需要这种工作流程:

  1. 将图像数据上传到显卡
  2. 转换图像
  3. 将结果下载回主存

每一步都会停止,直到上一步完成。这可以。我需要尽快完成所有这些步骤。与其他操作多路复用对我来说不是一个改进;我需要尽快完成这张图片。

现在,2 真的很快,3 也不错,很可能是因为结果是原始图像的缩略图——小得多。

1 是我的瓶颈。我测量了在 1.2 秒内上传 20MB 的图像数据。这让我达到了 16MB/s 的速度。我在 Internet 上的其他地方读到了有关 expecting 5.5GB/s, and being disappointed by 2.5GB/s 的人。

无论我是直接使用glTexImage2D 还是通过PBO 使用都没有关系。我都试过了,没有测量出任何区别。这是有道理的,因为我没有与任何东西进行多路复用。对于我的管道,无论如何我都无法在不立即停止的情况下使用 PBO。

我能想到的剩下的解释是:我的系统就是这么慢。我的显卡是 NVIDIA GPU GeForce GTX 285 (GT200),通过 16x PCI-Express 连接。我测得的 16MB/s 是不是和这个速度一样快,还是我忽略了什么?是否存在让我测量最大数据速率的实用程序(通常用于 Ubuntu/Linux)?

得出系统这么慢的结论让我感到不舒服;毕竟,我的网络接口速度非常快(1Gb/s ~ 125MB/s),并且只有 cat-5e 电缆可以实现这一点。


更多细节:glTexImage2D 案例非常简单:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rawData);

仅此行的时间测量约为 1200 毫秒。

如前所述,我也将其翻译为使用 PBO:

GLuint pbo = 0;
glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
glBufferData(GL_PIXEL_UNPACK_BUFFER, data_size, pixels, GL_STREAM_DRAW);
glTexImage2D(target, level, internalformat, width, height, border, format, type, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glDeleteBuffers(1, &pbo);    

我也尝试过内存映射:

glBufferData(GL_PIXEL_UNPACK_BUFFER, data_size, 0, GL_STREAM_DRAW);
GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
std::copy(pixels, pixels+data_size, ptr);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);

任何解决方案之间的时间没有明显差异。


上传纹理数据时我应该期望什么样的数据速率?

我的设置 16MB/s 是否合理? (我觉得“不”。如果是,请告诉我!)

有没有一种工具可以用来验证这是我的系统的速度,从而证明我的代码是正确的,或者可以肯定地将责任归咎于我的代码?

【问题讨论】:

  • 您确认上传时没有自动格式转换的风险吗?可以想象,这种转换可以由您的驱动程序在软件中完成,因此非常慢。
  • @unwind 我还没有验证这一点。我该怎么做呢?不过,这仍然很奇怪。我正在通过网络下载图像,解压缩 jpeg 并在 160 毫秒内将所有 R 与 B 切换。格式转换应该非常复杂,最多需要一秒钟..?
  • 如果多次使用同一个纹理对象并且纹理大小或内部格式没有改变,那么当然使用glTexSubImage2D而不是glTexImage2D将是一个开始,因为这不会每次都完全重新分配整个纹理,这可能需要驱动程序/硬件方面的大量维护工作。
  • @MagnusHoff 您可能只是尝试上传数据的不同格式(不是纹理的内部格式)。一些平台使用GL_BGRA 格式比GL_RGBA 更满意。并且使用布局,使用填充到 4/8 字节的行(以及适当的glPixelStore 设置)也可能是首选。
  • @ChristianRau 这是一次性的,所以glTexSubImage2D 也帮不了我:( 将继续测试其他纹理格式。

标签: opengl


【解决方案1】:

不,我并没有因为期待更高的数据传输率而疯狂。

我的错误是我将数据上传的时间设置在过高的抽象级别,所以我无意中将new Uint8Array(image.buffer) 包含在我的时间安排中。在一个时间里,我看到这个调用需要 1190 毫秒,而 glTexImage2D 需要 10 毫秒。

下一课:在特定 C 调用之前和之后的确切行上进行计时。只有这样我才发现问题所在。

非常感谢 @ChristianRau 帮助我完成调试。

【讨论】:

    猜你喜欢
    • 2020-01-01
    • 2015-08-11
    • 2022-01-08
    • 2018-11-13
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多