17

最近の質問に触発されて、インラインアセンブリや非標準のコンパイラ組み込み関数を使用せずに、Linux x86-64プラットフォームでgccx86-64命令(ビットテストおよびセット)を生成する方法を知っている人がいるかどうかを知りたいです。bts

関連する質問:

移植性は私にとってより重要なbtsので、ディレクティブは使用しませんasm。別の解決策がある場合は、コンパイラの本能を使用しないことを好みます。

編集:Cソース言語はアトミック操作をサポートしていないので、アトミックテストアンドセットを取得することに特に興味はありません(それが最初にテストアンドセットが存在する元々の理由ですが)。アトミックなものが必要な場合は、標準のCソースでそれを行う機会がないことがわかっています。それは、組み込み関数、ライブラリ関数、またはインラインアセンブリである必要があります。(複数のスレッドをサポートするコンパイラーでアトミック操作を実装しました。)

4

3 に答える 3

2

それは最初のリンクの最初の答えにあります-物事の壮大な計画においてどれだけ重要ですか。ビットをテストするときの唯一の部分は次のとおりです。

  • 低レベルのドライバー。ただし、おそらくASMを知っているものを作成している場合、システムに十分に調整されており、おそらくほとんどの遅延はI / Oにあります
  • フラグのテスト。これは通常、初期化 (最初に 1 回のみ) または共有計算 (はるかに時間がかかる) のいずれかです。

マイクロベンチマークで改善が見られたとしても、アプリケーションとマクロベンチマークのパフォーマンスへの全体的な影響は最小限にとどまる可能性があります。

編集部分へ-bts単独での使用は、操作の原子性を保証しません。保証されるのは、このコアでアトミックにorなることだけです(メモリでもそうです)。マルチプロセッサ ユニット (一般的ではない) またはマルチコア ユニット (非常に一般的) では、他のプロセッサと同期する必要があります。

同期ははるかに高価であるため、次の違いがあると思います。

asm("lock bts %0, %1" : "+m" (*array) : "r" (bit));

asm("lock or %0, %1" : "+m" (*array) : "r" (1 << bit));

最小限です。そして2番目のフォーム:

  • 一度に複数のフラグを設定できます
  • 素敵な__sync_fetch_and_or (array, 1 << bit)フォームを持っています (私が覚えている限り、gcc と Intel コンパイラで作業しています)。
于 2010-03-06T11:21:55.540 に答える
1

__sync_lock_test_and_set( http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html )などのgccアトミックビルトインを使用しています。-marchフラグを変更すると、生成されるものに直接影響します。私はi686今それを使用していますが、http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/i386-and-x86_002d64-Options.html#i386-and-x86_002d64-Optionsはすべてを示しています可能性。

まさにあなたが求めているものではないことは承知していますが、そのようなメカニズムを探していたときに、これらの 2 つの Web ページが非常に役立つことがわかりました。

于 2010-01-11T09:51:45.877 に答える
0

私は、C++ も C 標準も、これらのタイプの同期メカニズムのメカニズムをまだ持っていないと考えています (確実ではありません)。高レベルの同期メカニズムのサポートは、標準化のさまざまな段階にありますが、それらのいずれかが、目的のタイプのプリミティブへのアクセスを許可するとは思いません。

ロックが不十分なロックフリーのデータ構造をプログラミングしていますか?

おそらく、gcc の非標準の拡張機能や、オペレーティング システムまたはライブラリが提供する同期プリミティブをそのまま使用することをお勧めします。コンパイラ組み込み関数の使用を懸念している場合は、探しているタイプの移植性を提供するライブラリがあるに違いありません。(実際には、ほとんどの人は必要なときに gcc 固有のコードを使用するだけだと思います。理想的ではありませんが、標準は実際には追いついていません。)

于 2010-01-11T09:44:06.767 に答える