2

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

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

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

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

1是我的瓶颈。我测量了在 1.2 秒内上传 20MB 的图像数据。这让我达到了 16MB/s 的速度。在 Internet 的其他地方,我读到有人期望 5.5GB/s,但对 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);

仅对这条线计时即可测量 ~1200ms。

如前所述,我还将其翻译为使用 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 合理吗?(我觉得“不”。如果是,请告诉我!)

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

4

1 回答 1

0

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

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

下一次的教训:在特定的 C 调用之前和之后在准确的行上进行计时。直到那时我才发现问题所在。

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

于 2013-04-16T13:25:19.457 回答