1

データ視覚化アプリケーション (平行座標) を使用しています。これには、画面上に大量の線を描画することが含まれます。アプリケーションは、巨大なデータセット用です。テスト データ セットには、約 250 万行 (正確には 2527700 行) が含まれます。画面が乱雑になりますが、いくつかのパターンが表示されます。アプリケーションには、X と Y に沿ってスケーリングする機能があります。通常のズーム レベルでは、約 300K の線を描画します。アプリケーションは Qt で書かれており、レンダリングにかかる​​時間はかなりのものです。典型的な数値は (ミリ秒単位の時間)

かかった時間: 496 ドリュー 1003226 行

かかった時間: 603 ドリュー 1210032 行

かかった時間: 112 ドリュー 344582 行

かかった時間: 182 ドリュー 387960 行

かかった時間: 178 ドリュー 361424 行

かかった時間: 222 ドリュー 676470 行

かかった時間: 171 Drew 475652 行

かかった時間: 251 ドリュー 318709 行

かかった時間: 5 ドロー 14160 行

かかった時間: 16 Drew 27233 行

次のコード セグメントは、描画された線分の時間とカウントに使用されます。レンダリングは、オフスクリーン イメージ (フォーマット Format_ARGB32_Premultiplied の QImage) に対して行われます。QImage のサイズは最大 1366 x 768 です。セグメント タイプは QVector です。

QTime m_timer;
m_timer.start();
painter.drawLines(segments);
qDebug() << "Time taken: " << m_timer.elapsed();
painter.end();
qDebug() << "Drew " << segments.size();

この QImage は、将来の描画を保存するためにキャッシュされます。私は DirectX を使用したことがありません。Direct 2D レンダリングは、私が既に持っているものよりもパフォーマンス上の利点をもたらしますか? これらの数値を改善する方法はありますか?

Direct 2D レンダリングでこれらの数値を改善できる場合、どの技術スタックを使用すればよいですか? C#/SharpDX を使用したほうがよいでしょうか? Qtは翻訳のみでDirectXを実行でき(コストがいくらかはわかりません)、アプリが主にWindowsであるため、C#は開発を容易にする可能性があるため、これを尋ねます。処理する。

4

3 に答える 3

2

Qt はわかりませんが、Direct2D の場合、Windows 7 で何百万ものアンチエイリアス処理された線を描画すると、パフォーマンスが低下します (最新の IE10/SP の更新がなければ)。Windows 8 では、Direct2D がわずかに改善されましたが、そのようなレートを処理できるかどうかはわかりません。パフォーマンスを向上させたい場合は、直接 Direct3D を MSAA サーフェスで使用するか、FXAA のようなスクリースペース ポストエフェクトを使用するか、GPAA/GBAA のようなジオメトリに対応したアンチエイリアシング技術を使用する必要があります。最新のリアルタイム アンチエイリアシング技術の包括的なリスト「リアルタイム アンチエイリアシングのためのフィルタリング アプローチ」を確認してください。

于 2013-01-25T04:13:14.310 に答える
2

QImage メモリ バッファを直接操作して、独自の線描画関数を作成するのが最適な場合があります。そこでは、Qt のペインタがおそらくできないいくつかの仮定を行い、より良いパフォーマンスを達成することができます。次に、QGLWidget を使用して、イメージをスクリーンにブリットし、アンチエイリアス処理 (およびおそらくズーム) します。

良い線画コード: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#Simplification。ただし、C++ およびメモリ バッファーの実装の場合は、単一のポインターに置き換えx0y0調整することでさらに最適化できます。

最も重要なことは、行ループ内でインライン化された線画を取得し、100 万行を超える反復処理中に関数呼び出しをゼロにできることです。

ブリッティング部分にアンチエイリアシングをさせれば、ペンの種類などを確認せずに、ピクセルごとにメモリーワードを設定するだけで済みます。

また、任意のターゲット解像度に HW でズームすると、画面に表示するのとは別に、必要なパターンを取得するために QImage のサイズを自由に最適化できます。

ほとんどの行を Y 座標で並べ替えることができれば、キャッシングに役立ちます。連続行のピクセルを設定すると、QImage バッファーのメモリ内で近くなります。

ただし、最適化をクランクアップします(gccの-O3フラグ、MSコンパイラーは不明)、少なくともgccのデフォルトは最大ではありません。

他にできることは、画像ごとのレベルで描画を並列化することです。これは、QPainter でも機能します。メイン スレッド以外で QImage を描画することが許可されており、Qt を使用すると、QImage を描画スレッドから GUI スレッドにシグナル パラメータとして送信するだけで簡単に実行できます。あなたがしていることはCPUとメモリに大きく依存しているので、ハイパースレッディングを数えずに、描画スレッド数を実際のコア数と同じにすることをお勧めします。

于 2013-01-25T04:44:37.417 に答える
1

多分私はあなたの質問に直接答えませんが:

  • Qtは標準のシステムルーチンを使用してグラフィカル操作を実行していると思います。つまり、ここではGDIやGDI+を意味します。これらのどちらも高速であれば、どちらもCPUですべての計算を実行します。一方、DirectX11 +のDirect2Dは、可能であればGPUパワーを使用して描画を高速化しようとするため、より高速に動作する可能性があります。

  • Qtはよくわかりませんが、何らかの方法で描画したいウィンドウ(=コントロール)へのハンドルを取得できるはずです(WinAPIを使用することを意味する場合でも、常に方法があります)。その場合、すべてのQtメカニズムをバイパスし、DirectXを使用して、追加のオーバーヘッドなしでそのウィンドウに直接描画できます。

  • SharpDXに関しては-私はそのようなライブラリが存在することを知りませんでした、情報をありがとう。彼らは操作のパフォーマンスについて通知する論文を公開しました、あなたはそれをチェックしたいかもしれません:http: //code4k.blogspot.com/2011/03/benchmarking-cnet-direct3d-11-apis-vs.html。とにかく、それはDirectXヘッダーの多かれ少なかれ単純なラッパーのように見えるので、アプリケーションに多くのオーバーヘッドを追加するべきではありません(パフォーマンスが本当に重要でない限り)。

于 2013-01-24T09:42:48.493 に答える