6

Cで記述されたライブラリがあり、C ++とCで記述された2つのアプリケーションがあります。このライブラリは通信ライブラリであるため、API呼び出しの1つは次のようになります。

int source_send( source_t* source, const char* data );

Cアプリでは、コードは次のようになります。

source_t* source = source_create();
for( int i = 0; i < count; ++i )
    source_send( source, "test" );

C ++アプリがこれを行うのに対して:

struct Source
{
    Source()
    {
        _source = source_create();
    }

    bool send( const std::string& data )
    {
        source_send( _source, data.c_str() );
    }

    source_t* _source;
};

int main()
{
    Source* source = new Source();
    for( int i = 0; i < count; ++i )
        source->send( "test" );
}

Intel Core i7では、C ++コードは1秒あたりほぼ正確に50%多くのメッセージを生成します。一方、Intel Core 2 Duoでは、1秒あたりほぼ正確に同じ量のメッセージを生成します。(コアi7には4つのコアがあり、それぞれに2つの処理スレッドがあります)

これを実現するためにハードウェアがどのような魔法を実行するのか興味があります。私はいくつかの理論を持っていますが、私は本当の答えが得られると思いました:)

編集:コメントからの追加情報

コンパイラはビジュアルC++であるため、これはWindowsボックスです(両方とも)

通信ライブラリの実装により、メッセージを送信するための新しいスレッドが作成されます。source_createは、このスレッドを作成するものです。

4

5 に答える 5

7

ソースコードだけを調べても、C++コードの方が高速である理由はわかりません。

次に行うことは、生成されているアセンブリコードをチェックすることです。GNUツールチェーンを使用している場合、それを行うにはいくつかの方法があります。

-Sコマンドライン引数を介してアセンブリコードを出力するようにgccとg++に要求できます。その引数を追加する以外に、通常のコンパイルで使用するのとまったく同じコマンドライン引数を使用するようにしてください。

2番目のオプションは、gdbを使用してプログラムをロードし、disasコマンドを使用することです。

幸運を。

アップデート

Microsoftツールチェーンでも同じことができます。

コンパイラーにアセンブリーを出力させるには、/FAまたは/FAsのいずれかを使用できます。1つ目はアセンブリのみを出力し、2つ目はアセンブリとソースを混合します(これにより、追跡が容易になります)。

デバッガーの使用については、Visual Studioでデバッガーを起動したら、[デバッグ]、[Windows]、[逆アセンブリ]の順に移動します(Visual Studio 2005で確認済み、他のバージョンは異なる場合があります)。

于 2010-01-13T05:01:11.217 に答える
2

完全なコードまたはアセンブリを表示しない限り、C++ コンパイラがインライン展開していると推測できます。C++ コンパイラの優れた点の 1 つは、速度を上げるために何でもインライン化できることです。Microsoft のコンパイラは、最終的な実行可能ファイルを不当に肥大化させるところまで無償でインライン化することでよく知られています。

于 2010-01-13T06:00:05.030 に答える
1

最初にお勧めするのは、両方のバージョンのプロファイルを作成し、顕著な違いがあるかどうかを確認することです。

C バージョンは不必要に何かをコピーしていますか (戻り値の最適化のように微妙な最適化またはそれほど微妙ではない最適化である可能性があります)。

これは、優れたプロファイラーに表示されるはずです。ハイエンドの VS SKU を使用している場合は、サンプリング ベースのプロファイラーが適しています。優れた無料のプロファイラーを探している場合、Windows パフォーマンス アナライザーは Vista で非常に強力です。スタックウォーク オプションの使用

私がおそらく最初に行うことは、デバッガーに侵入し、それぞれの逆アセンブリを調べて、それらが著しく異なるかどうかを確認することです。asm をテキスト ファイルに出力するコンパイラ オプションがあることに注意してください。

明らかに明白なもの (余分なコピーなど) がなければ、これをプロファイルでフォローアップします。

もう 1 つ、ハイパー スレッドが邪魔になることが心配な場合は、プロセスを非 HT コアにハード アフィニティ化してください。これは、GUI のタスク マネージャーまたは SetThreadAffinityMask を介して行うことができます。

-リック

于 2010-01-13T05:52:54.030 に答える
0

Core i7はハイパースレッド化されています-HTを有効にしていますか?

たぶん、C ++コードはHTを利用するために何らかの形でコンパイルされていますが、Cコードはそうではありません。コードを実行しているときのタスクマネージャーはどのように見えますか?負荷をコアの数に均等に分散しますか、それとも少数のコアが最大になりますか?

于 2010-01-13T04:51:37.007 に答える
0

大雑把な推測: アプリケーションと共にライブラリ ソースをコンパイルしていて、C API 関数が extern "C" として宣言されていない場合、C++ バージョンは別の、何らかの方法でより高速な呼び出し規則を使用している可能性があります。

また、アプリケーションと一緒にライブラリ ソースをコンパイルしている場合、C++ コンパイラはライブラリ ソースを C++ としてコンパイルしており、C コンパイラよりも最適化が優れているのではないでしょうか?

于 2010-01-13T05:08:39.830 に答える