編集: ST では、初心者向けに 2 つ以上のリンクを投稿することは許可されていません。参照が不足していて申し訳ありません。
グローバル状態の変更の検出がパフォーマンスに関連する C アプリケーションでロックのオーバーヘッドを削減しようとしています。最近、このトピックについてかなり多くのことを読んでいますが (たとえば、H. Sutter などから多くのことを読んでいます)、自分の実装について確信が持てません。複数のスレッド間で共有されるデータからスレッド ローカル データを更新するために、 CASのような操作とDCLを組み合わせてCache-Line Alignedグローバル変数をチェックし、偽共有を回避したいと考えています。自信がないのは主に
- Type-Attributesに関する GNU ドキュメントの解釈に失敗しました
- STまたは1でのキャッシュラインへの整列およびキャッシュラインサイズの認識など、Cに簡単に変換できる文献や例を見つけることができないようです(1は答えているようですが)私の質問は、実装に自信がありません)
- 私のCの経験は限られています
私の質問:
タイプ属性のドキュメントには次のように記載されています。
この属性は、指定された型の変数の最小アラインメント (バイト単位) を指定します。たとえば、宣言は次のとおりです。
(宣言については、型属性のドキュメントを参照してください)
struct S
コンパイラーに、型が割り当てられている、または割り当てられる予定の各変数がmore_aligned_int
、少なくとも8-byte
境界で割り当てられ、整列されることを (できる限り) 保証するように強制します。SPARC では、型のすべての変数struct S
を境界に整列させる8-byte
ことで、コンパイラは型 struct S の変数を別の変数にコピーするときに ldd および std (ダブルワードのロードとストア) 命令を使用できるようになり、実行時の効率が向上します。struct S
それは、またはの始まりが常に境界more_aligned_int
に揃えられるということですか?8-byte
正確に 64 バイトを使用するためにデータがパディングされるという意味ではありませんよね?struct cache_line_aligned
1. のすべてのインスタンス(以下のコード例 1を参照) が境界上に位置合わせされ、正確に 1 つのキャッシュ ラインを使用することが true であると仮定します64-byte
(キャッシュ ラインが64 bytes
長さであると仮定します) 。型宣言に使用
typedef
しても、のセマンティクスは変更されません__attribute__ ((aligned (64)))
(以下のコード例 2を参照)。aligned_malloc
構造体がで宣言されている場合、構造体をインスタンス化するときに使用する必要はありません__attribute__ ...
// Example 1
struct cache_line_aligned {
int version;
char padding[60];
} __attribute__ ((aligned (64)));
// Example 2
typedef struct {
int version;
// place '__attribute__ ((aligned (64)))' after 'int version'
// or at the end of the declaration
char padding[60];
} cache_line_aligned2 __attribute__ ((aligned (64)));
最後に、キャッシュラインにアラインされたアプローチを使用して、グローバル状態が他のスレッドによって変更されたかどうかを効率的にチェックする関数のスケッチを示します。
void lazy_update_if_changed(int &t_version, char *t_data) {
// Assuming 'g_cache_line_aligned' is an instance of
// 'struct cache_line_aligned' or 'struct cache_line_aligned2'
// and variables prefixed with 't_' being thread local
if(g_cache_line_aligned.version == t_version) {
// do nothing and return
} else {
// enter critical section (acquire lock e.g. with pthread_mutex_lock)
t_version = g_cache_line_aligned.version
// read other data that requires locking where changes are notified
// by modifying 'g_cache_line_aligned.version', e.g. t_data
// leave critical section
}
}
長い投稿で申し訳ありません。
ありがとうございました!