5

非常にレイテンシーの影響を受けやすいアプリケーションを作成している場合、C++ 関数内にアセンブラーを埋め込むこと (および C++ 関数呼び出しを通常どおり使用すること) の制限は次のようになります。

inline __int64 GetCpuClocks()
{

    // Counter
    struct { int32 low, high; } counter;

    // Use RDTSC instruction to get clocks count
    __asm push EAX
    __asm push EDX
    __asm __emit 0fh __asm __emit 031h // RDTSC
    __asm mov counter.low, EAX
    __asm mov counter.high, EDX
    __asm pop EDX
    __asm pop EAX

    // Return result
    return *(__int64 *)(&counter);

}

(上記の関数は、私が見た別のSO投稿からのものです)

アセンブラでインライン化された関数をブラック ボックスのように扱えますか? アセンブラで実行した計算の結果を簡単に取得できますか? レジスタなどに現在どの変数が入っているかわからない危険性はありますか? それは解決するよりも多くの問題を引き起こしますか、それとも特定の小さなタスクには受け入れられますか?

(アーキテクチャが修正され、既知であると仮定します)

編集私はこれを見つけました、これは私がほのめかしているものです:

http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-CC

EDIT2 これは、Linux と x86 を対象としたものです。一般的な C++/アセンブラーの質問です (または、そう思いました)。

4

2 に答える 2

3

サブクエスチョンについて、次のように答えたいと思います。

それは解決するよりも多くの問題を引き起こしますか、それとも特定の小さなタスクには受け入れられますか?

確かにそうです!インライン アセンブラを使用すると、コンパイラの機能を利用してコードを最適化できます。部分的な式の置換やその他の派手な最適化を行うことはできません。コンパイラが -O3 で出力するものよりも優れたコードを生成するのは、本当に、本当に難しいです。おまけとして、コードは次のコンパイラ リリースでさらに改善されます (次のコンパイラ リリースで問題が発生しないと仮定して ;) )。

コンパイラーは通常、人間の脳がこれまでにできた (または健全性を確保するために必要な) よりも広い範囲を把握し、適切な関数を適切な場所にインライン化し、コードをより効率的にする部分的な式の置換を行うことができます。コードが地獄のように読めなくなるため、ASM では絶対にやらないこと。

逸話的な参考資料として、 libcrypt で手作業で最適化された SHA1 よりも優れている SHA1 の git 実装に関連する、Linus Torvalds によるこの投稿を参照したいと思います。

実際、最近のインラインアセンブラの唯一の合理的な使用法は、他の方法では利用できないプロセッサ命令を呼び出すことだと思います(引用したものは、たとえば Linux で利用できclock_gettimeます。少なくとも、高解像度の時間カウンターの後にのみ)または、コンパイラをだます必要がある場合(たとえば、外部関数インターフェイスの実装中)に何かをしなければならない場合。


スニペットと他の人が言ったことについて。特にそのような関数では、パフォーマンスが低下します。インライン asm では、レジスターがコンパイラーが想定する状態 (上記のプッシュ/ポップ) に保たれるように細心の注意を払う必要があります。一方、コードを通常どおりに記述した場合、コンパイラーは、レジスターで意味のある変数とスタックに収まらない変数を正確に管理して保持できます。

コンパイラを信頼してください。賢いです。ほとんどの時間。スマートで高速なアルゴリズムを考えたり、関連するコンパイラ スイッチを学習したりするためにインライン アセンブラを使用しないことで、節約した時間を投資してください (たとえば、SSE 最適化を有効にするなど)。

于 2012-12-11T20:39:16.647 に答える
1

問題の asm が使用するレジスターを一番上にプッシュしてから一番下にポップする場合、心配する必要はないと思います。

あなたの例では、これらは__asm push EAXおよび__asm pop EAX命令です。

本当の答えは、asm をブラック ボックスとして扱えるようにするために、asm が何をするかを十分に理解する必要があるということだと思います。:)

于 2012-12-11T20:20:59.533 に答える