16

この質問はすでにここに投稿していますが、Qt固有ではないかもしれないので、ここでもチャンスを試してみようと思いました。私はそれをするのが不適切ではないことを願っています(そうであるかどうか教えてください)。

私はいくつかの数学的計算を実行する小さな科学プログラムを開発しました。できるだけ速くなるように最適化しようとしました。これで、Windows、Mac、およびLinuxユーザーへの展開はほぼ完了しました。しかし、私はまだ多くの異なるコンピューターでそれをテストすることができませんでした。

困ったことは次のとおりです。Windowsに展開するために、Windows7とUbuntu12.04の両方がインストールされているラップトップを使用しました(デュアルブート)。これら2つのシステムで実行されているアプリの速度を比較したところ、Windowsでは少なくとも2倍遅いことにショックを受けました。小さな違いがあったとしても驚かなかったでしょうが、どうすればそのような違いを説明できるでしょうか。

ここにいくつかの精度があります:

  • 私がプログラムに行う計算は、残忍で愚かな数学的計算にすぎません。基本的には、10億回と呼ばれるループで製品と余弦定理を計算します。一方、計算はマルチスレッドです。6つのQThreadsのようなものを起動します。
  • ラップトップには、1.73Ghzの2つのコアがあります。最初は、Windowsはおそらくコアの1つを使用していないと思いましたが、小さな図によると、プロセッサのアクティビティを調べたところ、両方のコアが100%実行されています。
  • 次に、Windows用のC ++コンパイラは、Linux用のC ++コンパイラが(リリースビルドで)自動的に使用した最適化オプション(-O1 -O2など)を使用していないと思いましたが、明らかに使用しています。

Windowsではアプリの速度が非常に遅い(2〜4倍)のが気になりますが、それは本当に奇妙です。一方、私はまだWindowsを搭載した他のコンピューターで試していません。それでも、なぜ違いがあるのか​​分かりますか?

追加情報:いくつかのデータ…</ p>

Windowsは2つのコアを使用しているように見えますが、これはスレッド管理と関係があるのではないかと思います。理由は次のとおりです。

サンプル計算n°1(これは2つのQThreadsを起動します):

  • PC1-ウィンドウ:7.33秒
  • PC1-linux:3.72秒
  • PC2-linux:1.36s

サンプル計算n°2(これは3つのQThreadsを起動します):

  • PC1-ウィンドウ:6.84秒
  • PC1-linux:3.24s
  • PC2-linux:1.06s

サンプル計算n°3(これは6つのQThreadsを起動します):

  • PC1-ウィンドウ:8.35秒
  • PC1-linux:2.62s
  • PC2-linux:0.47秒

どこ:

  • PC1-windows = Windows 7を搭載した2コアラップトップ(@ 1.73Ghz)
  • PC1-linux = Ubuntu 12.04を搭載した2コアラップトップ(@ 1.73Ghz)
  • PC2-linux = Ubuntu 12.04を搭載した8コアのラップトップ(@ 2.20Ghz)

(もちろん、PC2の方が高速であることはショックではありません。私にとって信じられないのは、PC1-windowsとPC1-linuxの違いです)。

注:Mac OSで最近のPC(4または8コア@〜3Ghz、正確には覚えていません)でプログラムを実行しようとしましたが、速度はPC2-linuxと同等(またはわずかに高速)でした。

編集:コメントで尋ねられたいくつかの質問にここで答えます。

  • Qt SDKをWindowsにインストールしたばかりなので、すべての最新バージョン(MinGWを含む?)があると思います。コンパイラはMinGWです。Qtバージョンは4.8.1です。

  • 最適化フラグは、リリースモード(Qt Creatorを使用)でビルドすると自動的に使用されることに気付いたため、使用していません。QMAKE_CXXFLAGS + = -O1のようなものを書いた場合、これはデバッグビルドにのみ影響するように思われます。

  • スレッドなどの寿命:これは非常に簡単です。ユーザーが「計算」ボタンをクリックすると、2〜6個のスレッドが同時に起動され(計算対象によって異なります)、計算が終了すると終了します。派手すぎるものはありません。すべてのスレッドは残忍な計算を実行します(実際には、30ミリ秒ごとに(それほどではない)小さな計算を行い、基本的にエラーが十分に小さいかどうかをチェックする1つを除きます)。

編集:最新の開発と部分的な回答

これについての答えを提供するいくつかの新しい開発があります:

  • 速度の違いが本当にスレッドと関係があるのか​​どうかを判断したかったのです。そこで、計算で1つのスレッドのみを使用するようにプログラムを変更しました。これにより、「純粋なC++コード」のパフォーマンスをほぼ比較できます。現在、WindowsはLinuxよりもわずかに遅いだけであることが判明しました(15%程度)。したがって、違いのごく一部(重要ではない)はシステムに固有のものであると思いますが、大部分はスレッド管理によるものです。

  • コメントで誰か(Luca Carlon、ありがとう)が提案したように、私はMinGWの代わりにMicrosoft Visual Studio(MSVC)用のコンパイラを使用してアプリケーションを構築しようとしました。そして驚いたことに、(すべてのスレッドとすべてを含む)計算はLinuxよりも「わずか」20%から50%遅くなりました!私は先に進んでそれに満足するつもりだと思います。奇妙なことに、「純粋なC ++」の計算(スレッドが1つしかない)が(MinGWよりも)さらに遅くなったことに気づきました。これは全体的な違いを説明する必要があります。私の知る限り、MinGWは、moronのようにスレッドを処理することを除けば、MSVCよりもわずかに優れています

したがって、MinGW(理想的にはMSVCよりも使用したい)にスレッドをより適切に処理させるためにできることがあるか、それともできないかを考えています。私は驚かれることでしょう、どうしてそれがよく知られ、文書化されなかったのでしょうか?結論を出すのが早すぎることに注意する必要があると思いますが、(今のところ)1台のコンピューターで物事を比較しただけです。

4

5 に答える 5

4

別のオプションとして考えられるのは、Linux では qt がロードされているだけで、これは KDE を使用している場合に発生する可能性がありますが、Windows ではライブラリをロードする必要があるため、計算時間が遅くなります。ライブラリの読み込みがアプリケーションをどれだけ浪費するかを確認するには、純粋な C++ コードでダミー テストを作成します。

于 2012-10-15T09:59:20.247 に答える
0

Windows と Linux でミューテックスがどのように実行されるかによって、パフォーマンスの違いが生じる場合があります。

Windows 上の純粋なミューテックス コードは、ロック時にリソースの競合が発生するたびに 15 ミリ秒待機する可能性があります。Windows でより優れたパフォーマンスを発揮する同期メカニズムは、クリティカル セクションです。ほとんどの場合、通常のミューテックスで発生するロックのペナルティは発生しません。

Linux では、通常のミューテックスが Windows のクリティカル セクションと同じように機能することがわかりました。

于 2012-10-18T21:45:45.717 に答える
0

間違った方法でファイルを書き込むと、Windows での書き込みが非常に遅くなるというケースを 1 つ聞いたことがあります。(これは Qt とは関係ありません。)

その場合の問題は、開発者が SQLite データベースを使用し、約 10000 個のデータセットを作成し、COMMIT各挿入後に SQL を実行したことです。これにより、Windows では毎回 DB ファイル全体がディスクに書き込まれましたが、Linux では RAM 内のファイルシステム i ノードのバッファリングされたバージョンのみが更新されました。その場合の速度差はさらに悪く、Linux では 1 秒、Windows では 1 分でした。(最後に一度だけコミットするように SQLite を変更した後、Windows でも 1 秒でした。)

したがって、計算の結果をディスクに書き込んでいる場合は、fsync()またはfflush()頻繁に呼び出しているかどうかを確認する必要があります。記述コードがライブラリーからのものである場合は、これを使用できますstrace(Linux のみですが、基本的なアイデアが得られるはずです)。

于 2012-10-15T12:11:11.240 に答える
0

私のPCでもまったく同じ動作に気付きました。私は Windows 7 (64 ビット)、Ubuntu (64 ビット)、および OSX (Lion 64 ビット) を実行しており、私のプログラムは 2 つの XML ファイル (それぞれ 60Mb 以上) を比較しています。マルチスレッドも使用します(2スレッド):

-Windows : 40sec

-Linux : 14sec (!!!)

-OSX : 22sec.

Linux/OSX では「pthread」、Windows では「threads」を使用するスレッド (Qt ではなく) の個人クラスを使用します。Qt の XML クラスが必要なため、Qt/mingw コンパイラを使用します。

私は (今のところ) 3 つの OS が同様のパフォーマンスを持つ方法を見つけられませんでした... しかし、そうなることを願っています!

別の理由はメモリかもしれないと思います.私のプログラムは約500MbのRAMを使用しています. モノスレッドでは、Windows は正確に 1.89 倍遅く、Linux は 2 倍以上遅くなるとは思わないからです。

于 2013-03-19T11:31:33.717 に答える
0

おそらくメモリ アロケータです。Google のjemallocまたはtcmallocを使用してみてください。Glibc の ptmalloc3 は、MSVC の crt にある古い無愛想なアロケーターよりもはるかに優れています。Microsoft の同等のオプションはConcurrency CRTですが、単純に置き換えて使用することはできません。

于 2012-10-18T22:45:53.697 に答える