1

それぞれ 250 KB から 500 KB の約 6 つのファイルがあります。これらの各ファイルには、複数の QImages が含まれています。各ファイルには、128x64 の約 400 枚の画像があります。メモリへの読み込みは約 60MB/秒です (OpenGL は PNG を独自の形式に展開する必要があるため)。

このプロセスをスピードアップすることは可能ですか? 私はギグを埋めるために苦労しているので、それは骨の折れるほど遅いです.

QFile file("file.ucv");

if (file.open(QIODevice::ReadOnly)) {
    qDebug() << "Read from hdd";

    QDataStream r(&file);
    r.setVersion(QDataStream::Qt_4_3);

    QImage t;

    int i = maxPics * place;
    glGenTextures(maxPics, &texture[i]);
    for (int y = 0; y < yNrPics; y++)
        for (int x = 0; x < xNrPics; x++, i++) {

            // Write to precomputed object
            r >> t;

            glBindTexture( GL_TEXTURE_2D, texture[i] );
            glTexImage2D( GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
        }

プロファイラーは、この行が最も消費量が多いと判断します。

            glTexImage2D( GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );

圧縮を非圧縮に変更すると、多少時間が節約されますが、それでもそれほど多くはありません。

読み込まれた QImage は GLformat です。

4

2 に答える 2

2

データについて確実であることを確認してください。

  • つまり、プロファイラーが CPU 消費だけでなくウォールクロックを表示していることを確認してください (ディスク I/O は CPU を消費しませんが、時間がかかるため)。

また、作業を避けることが最善の最適化です。

  • 圧縮されたテクスチャを使用する場合は、テクスチャを 1 回だけ圧縮し (最初のアップロード)、圧縮されたデータをダウンロードしてディスクにキャッシュします。後続のアップロードでは、png-via-raw-to-gl から再圧縮することなく、圧縮データをディスクから OpenGL に直接送信する必要があります。

作業のパイプライン処理、特に I/O を使用した処理は、処理を高速化するための優れた方法であり、通常は簡単です (プロデューサーとコンシューマーの並列処理):

  • 画像の読み込みとテクスチャの作成に別のスレッドを使用して、アップロードをパイプライン処理します。Qt は、QtConcurrent ライブラリを通じてここで優れたサポートを提供します。つまり、自分でスレッドをいじる必要はありません。(ただし、QGLWidget::makeCurrent を使用する必要があります)

次のことが可能な場合は、CPU で使用可能なすべてのコアを使用します。

  • 複数のスレッドを使用してデータを OpenGL にアップロードすることを検討してください。ピクセル バッファー オブジェクトを使用すると、テクスチャ データ バッファーへのポインターを取得し、memcpy を使用してアップロードできます。(memcpy-threads はコンテキストをアクティブにする必要はありません。)
  • テクスチャ圧縮は GL ドライバーのソフトウェアで行われるため、コア間でアップロードを並列化するとここでも役立ちますが、GL ドライバーで並列に圧縮するには、(データを共有する) 複数の GL コンテキストを作成する必要がある場合があります。これを試す前に、並列かどうかを確認するのはそれほど難しくありません。

また、次の必要がない場合は、バッファリングされた API を介してデータをストリーミングしないでください。

  • ファイルをメモリ マッピングすることにより、データのアップロードを非常に効率的に行うことができます (バッファリングなし、ディスクから GL に直接)、マッピングされたバッファからテクスチャ ポインタへの memcpy だけです。
于 2012-04-29T20:10:21.087 に答える
1

ボトルネックがそのコードにあると確信している場合は、次のようなことがあります。

  • 使用しないでくださいGL_COMPRESSED_RGBA、しかし単にGL_RGBA
  • ドライバーの最適なタイプを見つけて、それを使用します(openglプログラムのプロファイルを作成する必要があります)
  • pngファイルで生データを使用する(圧縮を避ける)
  • ファイルを小さなファイルに分割する
于 2012-04-29T19:58:16.050 に答える