0

我前段时间问过这个问题,以了解加快图像写入文件的速度。我基本上有一个 OpenGL 应用程序。在每个渲染循环结束时,我将帧缓冲区保存到图像文件中。

   fbo.readFrame();

   glReadPixels(0, 0, _viewportWidth, _viewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, _data);
   _data.rewind(); //ByteBuffer
   new TImageExporter(ImageExporter.TGA, "renderings/", _data, _viewportWidth, _viewportHeight, true, _frameCount++).run();

TImageExporter 扩展了 Thread 并在“run()”方法中执行写入文件。令我惊讶的是,50 帧的渲染循环所用的时间几乎与我使用图像导出器的单线程版本一样。(3293 毫秒 - 多线程和 3437 毫秒使用单线程)。我在这里做错了什么?这是TImageExporter里面的代码:

public void export() {
    _pixels = new int[_width * _height];
    int bindex;
    int plenght = _pixels.length;
    // convert RGB data in ByteBuffer to integer array
    for (int i = 0; i < plenght; ++i) {
        bindex = i * 4;  //use 3 for RGB
          //// here write the pixels to RGBA/////
         ............
         .......................

    }

    _image.flush();
    _image.setRGB(0, 0, _width, _height, _pixels, 0, _width);
    _image = ImageUtils.flipY(_image);

    renderByFormatType();

}

private void renderByFormatType() {


    String formattedString = String.format(_formatString, _frameCount);

    if (_exportType.equals(TGA)) {
        try {
           writeTGA(_image, new File(_renderPath + "screenshot_test" + formattedString + ".tga"), _flipX);
        } catch (IOException ex) {
            Logger.getLogger(TImageExporter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }




}

@Override
public void run() {


        export();



}

更新:人们在这里问我是否写入同一个文件。不,每个线程都写入一个全新的文件。

UPDATE1:设置一个全局静态变量,保存 BufferedImage 数组。现在每个新的 TImageExporter 将图像数据写入该数组到不同的索引。直接写入磁盘时,我得到的只是 3038 毫秒而不是 3437 毫秒。

4

3 回答 3

3

多线程不会加速文件传输,因为:

  1. 当 1 个线程去保存它时,进行非线程安全的文件写入将覆盖其他线程正在写入的一些信息。

  2. 磁盘 I/O 是您的瓶颈。最好的办法是将您想要的内容写入内存流(有人编辑并提供文档,我无法快速找到它)并允许它写入磁盘..这将允许持续的磁盘 i/o 而无需担心线程

于 2012-08-01T17:40:46.293 回答
2

即使您的代码是多线程的;因为你所有的线程都试图访问同一个文件..它不会有太大的不同..因为在这种情况下,即使有很多线程正在运行;在某一时刻,除了 1 之外的所有内容都将等待获取对文件的写访问权限。

于 2012-08-01T17:40:01.157 回答
-1

为什么你认为它会更快?磁盘不是多线程的。

于 2012-08-01T22:27:45.843 回答