2012-12-11 8 views
5

そのようにあなたは、C++の機能の中にアセンブラを埋め込むには限界(および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); 

} 

(上記の関数がどこから来ました

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

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

EDIT2:

は、私はちょうどこれを見つけた

EDITを(あなたのアーキテクチャが固定されようとしていると仮定し、知られている)、これは私がほのめかしていますものですLinuxとx86-ちょうど一般的なC++ /アセンブラの質問(あるいは私は思った)。

+1

特にVisual C++について質問していますか?他のコンパイラには他の制約があるかもしれないと思います。 –

+0

@Robᵩいいえ、もしあれば、私はLinux、ICC、G ++を目指していました。私が見た最初のアセンブラ関数を手に入れました。 – user997112

+1

これはややこしいかもしれませんが、もしジャンプとリターンがあまりにも重いペナルティを負わなければ、純粋なアセンブラで(別のコンパイル単位で)アセンブラを書くことを考えてください。インライン化を避けることで、より効率的なキャッシュ利用によって遅延を改善することができます。 これは組み込みプラットフォームでより重要です。 – psyill

答えて

1

問題のasmがトップで使用しているレジスタをプッシュしていて、それらを最下部にポップしている場合、あなたはそれを心配しないで安全だと思います。

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

本当の答えは、あなたが十分なことを知って、あなたがそれをブラックボックスとして扱うことができるかどうかを知る必要があるということです。 :)私は、設問に答えるしたい

+0

それで基本的にあなたが始める状態があなたが終わった状態であることを確かめますか?アセンブラから計算を戻したい場合はどうしたらいいですか? – user997112

+0

うん、あなたは状態を台無しにしないでください。値を返すのはコンパイラによって決まると思います。 – Almo

3

は解決するよりも多くの問題が原因それをしない、またはそれは、特定の小さなタスクには受け入れられますか?

もちろんあります!インラインアセンブラを使用すると、コンパイラの機能を利用してコードを最適化できます。それは、部分式の代入や他のファンシーな最適化を行うことはできません。コンパイラが-O3を使って発行するコードよりも優れたコードを生成するのは本当に難しいです。また、ボーナスとして、次のコンパイラリリースでコードがさらに良くなりました(次のコンパイラリリースではそれが解消されないと仮定します))。

コンパイラは通常、人間の脳よりも広い範囲を把握しています(または、健全性を確保するために)。適切な関数を適切な場所にインライン展開し、コードをより効率的にする部分式置換を行うことができます。あなたのコードが地獄のように判読不能になるので、あなたはASMで決して行うことはありません。

参考文献として、libcryptの手で最適化されたSHA1を上回るSHA1のgit実装に関するLinus Torvaldsのthis postについてお伝えしたいと思います。

実際、インラインアセンブラの唯一の妥当な使い方は、最近では使用できないプロセッサ命令を呼び出すことだと思います(引用符で囲まれたものは、たとえばLinuxの場合はclock_gettimeとして利用できます。高分解能の時間カウンター)、あるいはコンパイラーを騙す必要がある場合(例えば、外部関数インターフェースの実装時など)、


スニペットと他の人が言ったことについて。特にこのような機能を使用すると、パフォーマンス上のペナルティが発生します。インラインasmでは、レジスタがコンパイラが想定している状態(上記のようにプッシュ/ポップ)に保たれるように注意する必要があります。通常、コードを記述すると、コンパイラはレジスタ内で意味をなさない変数やスタックに収まらない変数を正確に管理します。

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

+0

確かに、あなたは、コンパイラがすべてで驚くべきことではないと主張することができます。したがって、処理できる幅広いケースを補うために、小さな特定のタスクでは、プログラマがasm命令を少なく書くことができる多くの領域があります。 – user997112

+0

@ user997112あなたはどのような場合に留意していますか?数値と関係があることを考えれば、おそらくそれをカットすることはできません。また、リファレンスを入れ替えました。オリジナルのインラインASMには実際にインラインASMが含まれていました。 –

+0

何も念頭に置いてはいけませんが、領域コンパイラが悪いかどうかを知ることができれば、確かに有用でしょう。 – user997112

関連する問題