Más contenido relacionado
La actualidad más candente (20)
Más de Takashi Hoshino (20)
Intel TSX 触ってみた 追加実験 (TTAS)
- 1. Intel TSX HLE を触ってみた
追加実験 (TTAS)
2013-10-22
星野喬@サイボウズ・ラボ / @starpoz
1
- 3. TTAS (test-and-test-and-set)
• Test and test-and-set
class Spinlock // TTAS and HLE support
{
private:
char &lock_;
public:
explicit SpinlockHle(char &lock) : lock_(lock) {
int flags = __ATOMIC_ACQUIRE | __ATOMIC_HLE_ACQUIRE;
while (lock_ || __atomic_exchange_n(&lock_, 1, flags))
_mm_pause();
}
~SpinlockHle() noexcept {
int flags = __ATOMIC_RELEASE | __ATOMIC_HLE_RELEASE;
__atomic_clear(&lock_, flags);
}
};
3
- 4. 再実験
• Expr1: simple counter(s)
• Expr5: map operations
• 詳細は元資料参照のこと
– http://www.slideshare.net/starpos/intel-tsxhlex86opti6r2
4
- 5. 実験環境
• CPU: Core i7-4770
– 4cores 8HT
– HT 有効
– TurboBoost 有効
• メモリ: 16GB
• OS: Ubuntu 13.04 x86_64 kernel 3.8.19
• コンパイラ: GCC 4.8.1
– 最適化フラグ: -O2 のみ
5
- 6. 実験方法
• スレッドを必要なだけ起動して,X 秒間クリティカル
セクション (CS) を繰り返し実行
• Spinlock を使って CS の排他を取る
– HLE 有効/無効
– TTAS 有効/無効
– 終了判定のために CS 実行毎に atomic<bool> を load
するオーバーヘッドあり
• CS の実行回数の合計値を X で割ったものを
スループットとする
• 上記実験を Y 回行い,スループットの avg, min,
max を計算
6
- 7. Expr1: simple counter(s)
• クリティカルセクションループ
while (!isEnd_.load(std::memory_order_relaxed)) {
Spinlock<useHLE, useTTAS> lk(mutex_);
counter_++;
}
• パラメータ
– 競合率 100%: counter を全スレッドで共有
– 競合率 0%: スレッド毎に counter を持つ
• キャッシュラインが異なるように 64byte 毎に配置
Counter
Thread
競合率 100%
Thread
競合率 0%
Counter
7
- 10. Expr1 まとめ
• そもそも競合しやすい状況では HLE は投機
実行に失敗しやすいのでオーバーヘッドの分
だけ損
• 競合しにくい状況では HLE はスケールする
ため,オイシイ
• Expr1 だけ見ると,HLE の有無に関わらず
TTAS は常に効果がある
10
- 11. Expr5:
• 目的:
– 実用的なデータ構造で HLE の効果を知る
• 手段:
– Map<uint32_t, uint32_t> をひとつの spinlock
で排他
– read 比率を変える: 0%, 90%, 99%, 100%
• read 操作: ランダムキーで lower_bound 検索
• write 操作: ひとつ削除,その後 insert
– 初期アイテム数: 10K (約2MB), 1M (約100MB)
11
- 13. Expr5: 10K items read 0%
HLE なしだと TTAS の効果が大きい
このパラメータでは HLE はオーバーヘッド大
10 sec, 20 trials
13
- 14. Expr5: 10K items read 90%
HLE と TTAS を一緒に使うと並列度大の領域で効果が出る
ただし,並列度小だと HLE は足をひっぱる
10 sec, 20 trials
14
- 15. Expr5: 10K items read 99%
10 sec, 20 trials
HLE の効果が見える.TTAS と組み合わせると一長一短
15
- 16. Expr5: 10K items read 100%
HLE と TTAS の組み合わせが並列度大の領域で効果アリ
10 sec, 20 trials
TTAS ナシの場合は test-and-set の数によって律速しているのか?
16
- 17. Expr5: 1M items read 0%
HLE の有無よりも TTAS の有無が大きな効果
TTAS は競合が多いときに test-and-set の実行数が減り,
HLE は競合が少ないときに楽観的投機実行が成功しやすいので,
この結果と矛盾しない
10 sec, 20 trials
17
- 18. Expr5: 1M items read 90%
Read が増えたので,HLE の効果が相対的に大きくなった
10K items のときと同様に TTAS との組み合わせ効果は
並列度によって一長一短
10 sec, 20 trials
18
- 19. Expr5: 1M items read 99%
10 sec, 20 trials
さらに Read が増えたので並列度小の領域でも
HLE の楽観的実行が成功しやすくなったと思われる
19
- 20. Expr5: 1M items read 100%
TTAS と HLE の組み合わせが大きな効果を発揮
10 sec, 20 trials
20
- 22. Expr5: 10K items read 0%
10 sec, 20 trials
HLE は並列度小では無駄.
TTAS のみを有効にした方が余程良い結果.
22
- 23. Expr5: 10K items read 90%
10 sec, 20 trials
std::map と傾向は変わらないが,HLE が効きやすい?
(実際のメモリ使用量の違いのせいかも知れない)
23
- 24. Expr5: 10K items read 99%
10 sec, 20 trials
HLE を使った方が良い結果に(std::map は一長一短のまま)
ただし並列度 1 を除く.
24
- 25. Expr5: 10K items read 100%
read 99% と同様の結果.最高性能は std::map に及ばず
10 sec, 20 trials
25
- 27. Expr5: 1M items read 90%
アイテム数 10K から 1M に増えると
HLE のオーバーヘッドが相対的に小さくなったと見て良いか.
TTAS は常に有効.
並列度大の領域では HLE の投機実行失敗のペナルティが見える.
10 sec, 20 trials
27
- 28. Expr5: 1M items read 99%
10 sec, 20 trials
read 90% と同様の傾向.
投機実行が成功しやすくなり,さらにスケールする.
28
- 30. Expr5: まとめ
• HLE のない世界では TTAS は常に効果アリ
• HLE と TTAS を組み合わせると
– 並列度小だと投機実行そのものを抑えられてス
ループットが伸び悩むデメリットあり
– 並列度大だと一度に投機実行するスレッドを少な
く抑えることができるため効果あり
– 上記は今のところあまり自信のある仮説ではない
30
- 31. まとめ
• HLE と TTAS の組み合わせは一長一短
– デフォルトを選べと言われたら HLE + TTAS
– 競合 100% の状況では TTAS のみ使う
• HLE を使うべき条件
– 条件1: 競合が起きにくい (read 比率が高い)
– 条件2: クリティカルセクション実行時間が短い
– 条件3: アクセス対象メモリが少ない
• 条件 2, 3 を誰か探求してください..
31