歌舞伎座Tech#2 C++11 LT

586 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
586
On SlideShare
0
From Embeds
0
Number of Embeds
18
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

歌舞伎座Tech#2 C++11 LT

  1. 1. L丁 M.Fukasawa (新人)
  2. 2. C++11 の超すてき機能 • Atomic !! – ロックラインベースの同期メカニズム – Semaphore とかとは違うよ • TLS – __thread – さようなら thread key • Fence まで!? – barrier なんて使う人あんまりいなそう
  3. 3. Closure • まぁ、 Bytecode の言語は解るよ… – 動的な型付け => Atom – Atom のような抽象型に coerce すればいい
  4. 4. Native での Closure #include <stdio.h> #include <vector> #include <algorithm> int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int main() { std::vector<int> lst(data, &data[sizeof(data)]); int total = 0; int sub = 0; std::for_each(lst.begin(), lst.end(), [&] (int x) __attribute__((noinline)) { total += x; sub -= x; }); printf("total:%d sub:%dn", total, sub); return 0; }
  5. 5. 自動的に生成されるシンボル [fukasawa@pc ~]$ nm lambda 0000000000600df8 d _DYNAMIC 0000000000601000 d _GLOBAL_OFFSET_TABLE_ 0000000000400930 R _IO_stdin_used w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable w _Jv_RegisterClasses U _Unwind_Resume@@GCC_3.0 00000000004008a0 t _ZZ4mainENKUliE_clEi U _ZdlPv@@GLIBCXX_3.4 U _Znwm@@GLIBCXX_3.4 0000000000400ad0 r __FRAME_END__ 0000000000600df0 d __JCR_END__ 0000000000600df0 d __JCR_LIST__ 00000000006010a8 D __TMC_END__ 00000000006010a4 B __bss_start 0000000000601060 D __data_start 0000000000400850 t __do_global_dtors_aux
  6. 6. ほんとに? [fukasawa@pc ~]$ c++filt _ZZ4mainENKUliE_clEi main::{lambda(int)#1}::operator()(int) const
  7. 7. ASM _ZZ4mainENKUliE_clEi: .LFB3265: .cfi_startproc movq (%rdi), %rax addl %esi, (%rax) movq 8(%rdi), %rax subl %esi, (%rax) ret .cfi_endproc
  8. 8. OK, だいたい解った • 江添さんの言ってた通りだったね • 関数内関数のために暗黙に this のようなも のが作られるとなると – でもこれ TLS で大丈夫か – 参照を明示してる限り問題ないだろう
  9. 9. 試してみよう
  10. 10. Closure with TLS class Threadable { public: Threadable() {} virtual ~Threadable() {} void rock(const std::vector<int>& lst) { thread_local int total; std::for_each(lst.begin(), lst.end(), [&](int x) __attribute__((noinline)) { total += x; }); printf("total:%dn", total); } }; int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int main() { std::vector<int> someList(data, &data[9]); Threadable t; t.rock(someList); return 0; }
  11. 11. ASM (closure with TLS) _ZZN10Threadable4rockERKSt6vectorIiSaIiEEENKUliE_clEi: .LFB3272: .cfi_startproc addl %esi, %fs:_ZZN10Threadable4rockERKSt6vectorIiSaIiEEE5total@tpoff ret .cfi_endproc
  12. 12. SIMD で使える? #include <immintrin.h> (初期化が煩わしくなるので) _m128i を使って __v4si data[] = { ない {1, 2, 3, 4}, 悪い例 {1, 2, 3, 4}, /* 略 */ {1, 2, 3, 4}, }; int main() { std::vector<__v4si> lst(data, &data[9]); __m128i total = {0}; std::for_each(lst.begin(), lst.end(), [&](__v4si x) __attribute__((noinline)) { total = _mm_add_epi32((__m128i)total, (__m128i)x); }); //int tmp[4] __attribute__((aligned(16))); alignas(16) int tmp[4]; _mm_store_si128((__m128i*)tmp, total); printf("total:(%d,%d,%d,%d)n", tmp[0], tmp[1], tmp[2], tmp[3]); return 0; }
  13. 13. ASM (closure with SIMD) _ZZ4mainENKUlU8__vectoriE_clES_: .LFB3743: .cfi_startproc movq (%rdi), %rax vmovdqa (%rax), %xmm1 vpadd %xmm0, %xmm1, %xmm0 vmovdqa %xmm0, (%rax) ret .cfi_endproc
  14. 14. でも参照[&]にしておくと • Inline asm でハマりそう
  15. 15. Closure with Inline ASM __m128i total = {0}; std::for_each(lst.begin(), lst.end(), [&](__v4si x) __attribute__((noinline)) { asm volatile ("vpaddd %2, %1, %0" : "=x"(total) : "x"(total), "x"(x)); }); Constraints として “x” (レジスタ直接)指定している
  16. 16. ASM (Closure with Inline asm) .type _ZZ4mainENKUlU8__vectoriE_clES_, @function _ZZ4mainENKUlU8__vectoriE_clES_: .LFB3743: .cfi_startproc movq (%rdi), %rax vmovdqa (%rax), %xmm1 vpaddd %xmm0, %xmm1, %xmm0 vmovdqa %xmm0, (%rax) ret .cfi_endproc
  17. 17. Thanks!

×