27

私たちの Web サーバーは、結果を Web クライアントに送信する前に、大きな画像の多くの構成をまとめて処理する必要があります。サーバーは 1 時間あたり数千の要求を受信する可能性があるため、このプロセスはパフォーマンスが重要です。

現在、私たちのソリューションは HD から PNG ファイル (それぞれ約 1MB) をロードし、それらをビデオ カードに送信して、合成が GPU で行われるようにします。最初に、XNA API によって公開された PNG デコーダーを使用して画像を読み込んでみました。パフォーマンスがあまり良くないことがわかりました。

問題が HD からの読み込みにあるのか、PNG のデコードにあるのかを理解するために、ファイルをメモリ ストリームに読み込み、そのメモリ ストリームを .NET PNG デコーダーに送信することで問題を修正しました。XNA を使用した場合と System.Windows.Media.Imaging.PngBitmapDecoder クラスを使用した場合のパフォーマンスの違いは重要ではありません。ほぼ同じレベルのパフォーマンスが得られます。

ベンチマークは、次のパフォーマンス結果を示しています。

  • ディスクからの画像のロード: 37.76ms 1%
  • PNG のデコード: 2816.97ms 77%
  • ビデオ ハードウェアへの画像の読み込み: 196.67ms 5%
  • 構成: 87.80ms 2%
  • ビデオ ハードウェアから合成結果を取得: 166.21ms 5%
  • PNG へのエンコード: 318.13ms 9%
  • ディスクへの保存: 3.96ms 0%
  • クリーンアップ: 53.00ms 1%

合計: 3680.50ms 100%

これらの結果から、PNG をデコードするときが最も遅い部分であることがわかります。

そのため、PNG のデコード時間を短縮できる PNG デコーダーがないのではないかと考えています。画像を非圧縮のままハードディスクに保存することも検討しましたが、1 枚の画像のサイズが 1MB ではなく 10MB になり、ハードディスクには数万枚の画像が保存されているため、すべての画像を圧縮せずに保存することはできません。圧縮。

編集:より有用な情報:

  • ベンチマークは、20 個の PNG 画像の読み込みとそれらの合成をシミュレートします。これは、本番環境で受け取るリクエストの種類にほぼ対応しています。
  • コンポジションで使用される各画像のサイズは 1600x1600 です。
  • このソリューションには、ここで説明しているような負荷分散されたサーバーが 10 台ほど含まれます。したがって、追加のソフトウェア開発作業は、ハードウェア コストの節約に見合う価値があります。
  • デコードされたソース画像をキャッシュすることを検討していますが、各コンポジションは完全に異なるソース画像で行われる可能性が高いため、キャッシュ ミスは高くなり、パフォーマンスの向上は低くなります。
  • ベンチマークは質の悪いビデオ カードで行われたため、まともなビデオ カードを使用すると、PNG のデコードがさらにパフォーマンスのボトルネックになることが予想されます。
4

4 に答える 4

6

別のオプションがあります。つまり、独自の GPU ベースの PNG デコーダーを作成します。OpenCL を使用して、この操作をかなり効率的に実行できます (また、OpenCL とリソースを共有できる OpenGL を使用してコンポジションを実行できます)。スループットを最大化するために、転送とデコードをインターリーブすることも可能です。これがあなたが追求できる/追求したいルートである場合、私はより多くの情報を提供できます.

GPU ベースの DEFLATE (および INFLATE) に関連するリソースを次に示します。

  1. GPU による可逆圧縮の高速化
  2. Google コードで CUDA を使用したgpu-block-compression 。
  3. GPU での 75 Gb/s での浮動小数点データ圧縮- これは INFLATE/DEFLATE を使用せず、より GPU に適した新しい並列圧縮/解凍スキームを使用することに注意してください。

お役に立てれば!

于 2012-07-03T14:57:41.750 に答える
4

次の2つのことを試しましたか。

1)
マルチスレッド、これを行うにはいくつかの方法がありますが、1つは「オールイン」メソッドです。基本的に、完全なプロセスのために X 量のスレッドを完全に生成します。

2)
おそらく、XX スレッドにすべての CPU 作業を実行させてから、それを GPU スレッドにフィードすることを検討してください。

あなたの質問は新しいユーザー向けに非常によく練られていますが、シナリオに関するいくつかの情報は役に立つでしょうか? バッチ ジョブまたはリアルタイムのサービス画像について話しているのでしょうか? 10kの写真は変わりますか?

ハードウェア リソース
処分時に所有しているハードウェア リソースも考慮する必要があります。通常、2 つの最も安価なものは CPU パワーとディスク容量です。そのため、めったに変化しない 10,000 枚の画像しかない場合は、それらすべてをより迅速に処理できる形式に変換することをお勧めします。

マルチスレッドのトリビア マルチスレッド
を行う際に考慮すべきもう 1 つのことは、スレッドを BellowNormal 優先度にするのが通常は賢明であることです。そのため、システム全体を「ラグ」にしないでください。使用するスレッドの量を少し試してみる必要があります。運が良ければコアあたりの速度が 100% 近く向上しますが、これは実行しているハードウェアとコードに大きく依存します。

私は通常Environment.ProcessorCountを使用して現在の CPU 数を取得し、そこから作業します :)

于 2012-07-03T14:51:18.103 に答える
3

私は純粋な C# PNG コーダー/デコーダー ( PngCs ) を作成しました。しかし、私はそれがより高速なパフォーマンスを持っていることを非常に疑っています[*]。高度に最適化されているわけではなく、巨大な画像を処理するためのメモリ使用量を最小限に抑えようとします(行ごとに順次エンコード/デコードします)。しかし、おそらくそれは、より優れた圧縮/解凍の実装をプラグインするためのボイラープレートとして機能します。私が見ているように、速度のボトルネックは zlib (インフレータ/デフレータ) であり、(Java とは対照的に) C# でネイティブに実装されていません。純粋な C# マネージド コードで SharpZipLib ライブラリを使用しました。これはあまり効率的ではありません。

ただし、あなたのテストでは、デコードがエンコードよりもはるかに遅いことに少し驚いています。ほとんどの圧縮アルゴリズム (おそらくすべて; そして確かに zlib) では、エンコードはデコードよりもはるかにコンピューター集約的であるため、私には奇妙に思えます。よろしいですか?(たとえば、5000x5000の RGB8 画像 (あまり圧縮できず、ディスク上で約 20MB) を読み書きするこの速度テストでは、書き込みに約 4.5 秒、読み取りに 1.5 秒かかります)。おそらく、純粋な PNG デコード以外に別の要因があるのでしょうか?

[*] 更新: いくつかの最適化を含む新しいバージョン (1.1.14 以降)。特に.Net 4.5を使用できる場合は、デコード速度が向上するはずです。

于 2012-07-03T23:15:15.900 に答える
2

複数のオプションがあります

  • デコード処理のパフォーマンスを向上させる

    別のより高速な png デコーダーを実装することができます (libpng はより高速な標準ライブラリです) より単純で高速なデコード可能な圧縮を使用する別の画像形式に切り替えることができます

  • 並列化

    .NET 並列処理機能を使用して、同時にデコードします。デコードはシングルスレッドである可能性が高いため、マルチコア マシンで実行する場合に役立つ可能性があります

  • ファイルを圧縮せずに保存しますが、圧縮するデバイスに保存します

    たとえば、圧縮フォルダーやサンドフォース ssd などです。これでも圧縮は行われますが、別の方法で圧縮され、解凍によって他のソフトウェアに負担がかかります。これが本当に役立つかどうかはわかりません。これは最後の手段としてのみ試してください。

于 2012-07-03T15:44:51.547 に答える