2017-06-22 15 views
0

2つの変数をアトミックにインクリメントすることは可能ですか?私は以下のコードを持っています。マルチプロセッサ、マルチスレッド環境なので、キャッシュの無効化はパフォーマンスのボトルネックになります。だから、私は原子操作の数を最小限にしようとしています。原子操作 - C

__sync_add_and_fetch(&var1,1); 
__sync_add_and_fetch(&var2,1); 

最初の引数がポインタであることがわかります。構造体を使用して私のケースを達成することは可能でしょうか?

P.S:ロックを使用できません。

+3

これは、変数の実際のタイプに完全に依存します。彼らが小さいタイプなら、様々なハッキングが可能です。 – Lundin

答えて

3

原子操作は非常に特殊であり、限られたサポートしか提供しません。 2つの変数にそれらを適用することは私にとっては不可能です。

原子操作が実際にrespで行われていることを保証していないことにも注意してください。 (すなわち、マシンコードコマンド)。

gccドキュメントの外にあります。 5.47 Built-in functions for atomic memory access

一部の操作はすべてのターゲットプロセッサでサポートされているわけではありません。ターゲットプロセッサ上で特定の操作を実装できない場合は、警告が生成され、外部関数が呼び出されます。外部関数は、ビルトインと同じ名前を持ち、追加の接尾辞 '_n'を持ち、nはデータ型のサイズです。

外部関数は、おそらくミューテックスを使用してアトミック操作をエミュレートします。

しかし、私は、それが「汚いハック」でのみ、特定の制限が可能であろうと思います。

16ビット符号なしカウンタが十分であれば、あなたはどこc1c2 += 0x00000001ずつ1つの32ビット変数でそれらのうちの2つを入れることができます一c1c2 += 0x00010000他をインクリメントし、インクリメントc1c2 += 0x00010001 またはアトミック操作を使用して、両方:

/* combined counters c1 and c2 */ 
static uint32_t c1c2 = 0; 

/* count c1 atomically */ 
__sync_fetch_and_add(&c1c2, 0x00000001); 
/* count c2 atomically */ 
__sync_fetch_and_add(&c1c2, 0x00010000); 
/* count c1 AND c2 atomically */ 
__sync_fetch_and_add(&c1c2, 0x00010001); 

これは、適切なビットがシフトしinvidiualカウンタ値にアクセスするためのマスクと組み合わされなければなりません。

もちろん、カウンタのオーバーフローが問題になる可能性があります。同じことが、64ビットプラットフォーム上の2つの32ビットカウンタで機能するかもしれません(アトミック演算は通常、「機械語」の幅でのみ使用可能です)。

Btw。背景情報のためにグーグルでは、私はつまずいた:Why does __sync_add_and_fetch work for a 64 bit variable on a 32 bit system?。私は、原子操作では、適切に動作するための変数の十分なアライメントが必要になるかもしれないというヒントを発見しました。

これは、C11 Atomic Libraryが原子変数に専用のタイプを提供する理由(例えば、atomic_uint_least32_t)が原因である可能性があります。

+0

ありがとうございます@Scheff。これは大いに役立ちます。 –