26. Volatile コード例 (C++)
26
// デバイス側で変更されるフラグ
extern volatile int flag;
int wait() {
// busy-loop でチェック
// 外部で flag が true になれば抜ける
while (!flag) {};
}
Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
27. 注意点
○ 各同期オブジェクトが使用できる/できないは OS や言語によって違う
○ 各同期オブジェクトがプロセス間で共有できる/できないは OS 依存
○ C++ の各オブジェクト操作が OS のどの API に相当するかは stdlib の実装依存となっ
ている
○ パフォーマンスが必要なら軽い API に切り替える必要がある
○ スペースの都合上ヘッダの include は省略した
○ 共有オブジェクトが static 変数になっているのはスペースの都合上なので実装ではやら
ないこと
27Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
34. Sleep 時間はベストエフォート
○ 各種 sleep/待機関数に渡す時間はその時間での起動を保証しない
○ スレッドスケジューリング (スレッド優先度等) の都合上起動が待たされる可能性が
ある
○ また、起動の精度はタイマー割り込みの頻度に依存する
○ Windows: 16 millisecond (デフォルト状態)
○ PC Linux: 4 millisecond (2010 の情報)
34Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
35. 精密な Sleep 時間が必要な場合
○ 精密に起動できるようにする
○ タイマー割り込み頻度の変更 (1 msec 精度まで)
○ スレッド優先度の引き上げ
○ Busy loop の採用
35Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
36. 5:Atomic 変数操作
36Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
37. ロックによるオーバヘッド
○ 頻繁にアクセスする変数にロックをかけるとパフォーマンス低下
○ 頻繁な状態チェック
○ API 呼び出し -> カーネル空間への移動
○ メモリを Atomic に操作する変数 (正確にはメモリを Atomic に操作する CPU 命
令) を使えばパフォーマンスが向上する
37Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
38. Atomic 変数の前に – data race の原因
○ コードと CPU 命令の乖離
○ CPU 内部の都合
○ キャッシュの同期が基本行われない
38Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
39. Data race : コードと CPU 命令の乖離 (1)
○ 下の処理中でコンテキストスイッチとなった場合、
再開時は昔のメモリを読み込んだ状態で処理再開
される
39
int func(int *ptr) {
*ptr++;
}
int func(int *ptr) {
int val = *ptr;
val++;
*ptr = val;
}
おおよそ
次のように展開される
Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
40. Data race : コードと CPU 命令の乖離 (2)
○ 変数がレジスタ幅に収まらない場合、メモリ書き込
み途中で他スレッドから読み取られる可能性がある
○ 矛盾した状態を読み込んでしまう
40
struct St {
int64_t a;
int64_t b;
};
int set(St *ptr) {
*ptr = { 123, 125 };
}
おおよそ
次のように展開される
struct St {
int64_t a;
int64_t b;
};
int set(St *ptr) {
ptr->a = 123;
ptr->b = 125;
}
Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
41. Data race : CPU キャッシュ (1)
41
メインメモリ (DRAM)
L3 キャッシュ
L1 キャッシュ
L2 キャッシュL2 キャッシュ
L1 キャッシュ
Core 1 Core 2
○ メモリアクセスは遅いのでキャッ
シュ階層を設ける
○ 容量と速度の要請から複数段に分か
れている
○ Core に近いキャッシュは Core ごと
に用意されている
Copyright ? PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.