編集:STは、初心者のために2つ以上のリンクを投稿することを許可していません。不足している参照を申し訳ありません。キャッシュラインアラインメントを使用したCのグローバル共有状態の変更のロックフリーチェック
グローバルな状態で変更が検出されたことがパフォーマンスに関連するCアプリケーションで、ロックオーバーヘッドを減らそうとしています。最近、話題についてかなり多くのことを読んでいましたが(例:H. Sutterなど)、私の実装については自信を持っていません。私はキャッシュライン整列グローバル変数のチェックのためにCASのような操作とDCLの組み合わせを使用して、誤った共有を回避し、複数のスレッド間で共有されたデータからスレッドローカルデータを更新したいと考えています。自信の私の欠如は、私は簡単なaligning-として、Cに変換する可能性のある文学と例を見つけることができないように見えるため、
- 私はType-Attributes
- にGNUのドキュメントを解釈するために失敗に主ですキャッシュ・ライン・アンド・知って・キャッシュ・ライン・サイズをSTまたは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参照)64-byte
境界に整列し、正確に一つのキャッシュラインを利用することは事実であるタイプ宣言がないためtypedef
を使用(キャッシュラインを仮定し、長さが
64 bytes
です)__attribute__ ((aligned (64)))
のセマンティクスを変える構造体が__attribute__ ...
と宣言されている場合、構造体のインスタンスを作成する際に、私は
(以下のコード例2を参照してください)
aligned_malloc
を使用する必要はありません
// 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
}
}
長い記事のために申し訳ありません。
ありがとうございました!
乾杯!これは物事を非常によく分かりました。私はsizeofを使ってアラインメントをチェックすることを考えていませんでした!私はこれを覚えています。動的に割り当てられた構造体はどうでしょうか? 'aligned_malloc'は仕事をしますか? – instilled
それはおそらくあります。その文書を読んで確認してください。 –
そうするでしょう。華麗な答えにもう一度感謝します。 – instilled