Dconf 2017
1日目
Pointers Gone Wild: Memory Safety and D
Dの作者ことうぉるたん。コンパイラの恩恵を受けるために生ポインタを使うよりref使おうとか、return refやscope refとか追加した理由とか。スライドにD言語くんがいっぱい登場していた。
D as a Better C
基本CとC++のdisで、後半はプロジェクトの事例紹介。
あまり期待していたような話はなかった。
Where Art Thou, LDC?
LDCのコアコミッタの人。発表はみてなくて後でスライドみただけ。ここ最近のLDCの活動(PGOとかLTOとか最適化のためのオプション追加したとか)、将来のビジョン(リンカにLLD使いたいとか、RISC-Vターゲットとか)。
What’s GNU With You?
GDCの中の人の話。GDBのD言語サポートがんばってる話(DWARF対応まわりとか、addr2line -C dlangとかでdemangleできるよ、とか)。
ABIまわりとか大変そうな雰囲気だった。ここは難しくてあまり理解できていない。
2日目
Things that Matter
C++界の巨人、Scott Mayer。効率/速度、ポータビリティ、ツーラビリティ(リファクタリングの話は笑った)、一貫性、インターフェース、コミットメントがこれまでの経験を通して大事であるという話。
Abstraction Cost and Optimization (LDC)
LDCでどういう風に書けば効率的なアセンブラを吐けるかという話。
いろいろなケースが紹介されている。単純な例でいうと、以下のコードはコンパイル時に定数になって効率的なアセンブラになっている。
import std.algorithm; import std.range; auto hoge() { return 1.iota(10) .map!(a => a * 2) .reduce!((a, b) => a + b); } /* $ ldc2 -c -O3 hoge.d $ objdump -Cd -Mintel hoge.o ... 0000000000000000 <_D4hoge4hogeFNaNfZi>: 0: b8 5a 00 00 00 mov eax,0x5a 5: c3 retq ... */
また、以下のコードはポインタでなくrefを使うとループのところでSIMDを使ったアセンブラを生成してくれる。
extern(C): alias T = int; T byPtr(int n, T *c) { T sum; for (int i=0; i < n; ++i) if (i > 0) sum += *c; return sum; } T byRef(int n, ref T c) { T sum; for (int i=0; i < n; ++i) if (i > 0) sum += c; return sum; } int f(int);
生成されるアセンブリ (これもobjdump -Cd -Mintel)
ref.o: file format elf64-x86-64 Disassembly of section .text.byPtr: 0000000000000000 <byPtr>: 0: 31 c0 xor eax,eax 2: 85 ff test edi,edi 4: 7e 56 jle 5c <byPtr+0x5c> 6: 8d 47 ff lea eax,[rdi-0x1] 9: 89 f9 mov ecx,edi b: 83 e1 03 and ecx,0x3 e: 83 f8 03 cmp eax,0x3 11: 73 06 jae 19 <byPtr+0x19> 13: 31 d2 xor edx,edx 15: 31 c0 xor eax,eax 17: eb 28 jmp 41 <byPtr+0x41> 19: 29 cf sub edi,ecx 1b: 31 d2 xor edx,edx 1d: 31 c0 xor eax,eax 1f: 90 nop 20: 85 d2 test edx,edx 22: 7e 02 jle 26 <byPtr+0x26> 24: 03 06 add eax,DWORD PTR [rsi] 26: 85 d2 test edx,edx 28: 78 02 js 2c <byPtr+0x2c> 2a: 03 06 add eax,DWORD PTR [rsi] 2c: 83 fa ff cmp edx,0xffffffff 2f: 7c 02 jl 33 <byPtr+0x33> 31: 03 06 add eax,DWORD PTR [rsi] 33: 83 fa fe cmp edx,0xfffffffe 36: 7c 02 jl 3a <byPtr+0x3a> 38: 03 06 add eax,DWORD PTR [rsi] 3a: 83 c2 04 add edx,0x4 3d: 39 d7 cmp edi,edx 3f: 75 df jne 20 <byPtr+0x20> 41: 85 c9 test ecx,ecx 43: 74 17 je 5c <byPtr+0x5c> 45: f7 d9 neg ecx 47: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0] 4e: 00 00 50: 85 d2 test edx,edx 52: 7e 02 jle 56 <byPtr+0x56> 54: 03 06 add eax,DWORD PTR [rsi] 56: ff c2 inc edx 58: ff c1 inc ecx 5a: 75 f4 jne 50 <byPtr+0x50> 5c: c3 ret Disassembly of section .text.byRef: 0000000000000000 <byRef>: 0: 31 c0 xor eax,eax 2: 85 ff test edi,edi 4: 0f 8e 58 01 00 00 jle 162 <byRef+0x162> a: 8b 0e mov ecx,DWORD PTR [rsi] c: 31 f6 xor esi,esi e: 83 ff 08 cmp edi,0x8 11: b8 00 00 00 00 mov eax,0x0 16: 0f 82 34 01 00 00 jb 150 <byRef+0x150> 1c: 89 fa mov edx,edi 1e: 83 e2 f8 and edx,0xfffffff8 21: b8 00 00 00 00 mov eax,0x0 26: 0f 84 24 01 00 00 je 150 <byRef+0x150> 2c: 66 0f 6e c1 movd xmm0,ecx 30: 66 0f 70 c0 00 pshufd xmm0,xmm0,0x0 35: 8d 42 f8 lea eax,[rdx-0x8] 38: c1 e8 03 shr eax,0x3 3b: 44 8d 40 01 lea r8d,[rax+0x1] 3f: 41 83 e0 01 and r8d,0x1 43: 85 c0 test eax,eax 45: 0f 84 a4 00 00 00 je ef <byRef+0xef> 4b: 41 8d 70 ff lea esi,[r8-0x1] 4f: 29 c6 sub esi,eax 51: 66 0f ef e4 pxor xmm4,xmm4 55: 66 0f 6f 2d 00 00 00 movdqa xmm5,XMMWORD PTR [rip+0x0] # 5d <byRef+0x5d> 5c: 00 5d: 66 44 0f 6f 05 00 00 movdqa xmm8,XMMWORD PTR [rip+0x0] # 66 <byRef+0x66> 64: 00 00 66: 66 44 0f 6f 0d 00 00 movdqa xmm9,XMMWORD PTR [rip+0x0] # 6f <byRef+0x6f> 6d: 00 00 6f: 66 44 0f 6f 15 00 00 movdqa xmm10,XMMWORD PTR [rip+0x0] # 78 <byRef+0x78> 76: 00 00 78: 66 44 0f 6f 1d 00 00 movdqa xmm11,XMMWORD PTR [rip+0x0] # 81 <byRef+0x81> 7f: 00 00 81: 66 0f ef f6 pxor xmm6,xmm6 85: 66 0f ef db pxor xmm3,xmm3 89: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] 90: 66 0f 6f cd movdqa xmm1,xmm5 94: 66 41 0f fe c8 paddd xmm1,xmm8 99: 66 0f 6f d5 movdqa xmm2,xmm5 9d: 66 41 0f fe d1 paddd xmm2,xmm9 a2: 66 0f 6f fd movdqa xmm7,xmm5 a6: 66 0f 66 fc pcmpgtd xmm7,xmm4 aa: 66 0f 66 cc pcmpgtd xmm1,xmm4 ae: 66 0f db f8 pand xmm7,xmm0 b2: 66 0f db c8 pand xmm1,xmm0 b6: 66 0f fe fe paddd xmm7,xmm6 ba: 66 0f fe cb paddd xmm1,xmm3 be: 66 0f 6f dd movdqa xmm3,xmm5 c2: 66 41 0f fe da paddd xmm3,xmm10 c7: 66 41 0f fe eb paddd xmm5,xmm11 cc: 66 0f 66 d4 pcmpgtd xmm2,xmm4 d0: 66 0f 66 dc pcmpgtd xmm3,xmm4 d4: 66 0f db d0 pand xmm2,xmm0 d8: 66 0f db d8 pand xmm3,xmm0 dc: 66 0f fe d7 paddd xmm2,xmm7 e0: 66 0f fe d9 paddd xmm3,xmm1 e4: 83 c6 02 add esi,0x2 e7: 66 0f 6f f2 movdqa xmm6,xmm2 eb: 75 a3 jne 90 <byRef+0x90> ed: eb 10 jmp ff <byRef+0xff> ef: 66 0f ef d2 pxor xmm2,xmm2 f3: 66 0f 6f 2d 00 00 00 movdqa xmm5,XMMWORD PTR [rip+0x0] # fb <byRef+0xfb> fa: 00 fb: 66 0f ef db pxor xmm3,xmm3 ff: 45 85 c0 test r8d,r8d 102: 74 28 je 12c <byRef+0x12c> 104: 66 0f 6f 0d 00 00 00 movdqa xmm1,XMMWORD PTR [rip+0x0] # 10c <byRef+0x10c> 10b: 00 10c: 66 0f fe cd paddd xmm1,xmm5 110: 66 0f ef e4 pxor xmm4,xmm4 114: 66 0f 66 cc pcmpgtd xmm1,xmm4 118: 66 0f db c8 pand xmm1,xmm0 11c: 66 0f fe d9 paddd xmm3,xmm1 120: 66 0f 66 ec pcmpgtd xmm5,xmm4 124: 66 0f db e8 pand xmm5,xmm0 128: 66 0f fe d5 paddd xmm2,xmm5 12c: 66 0f fe d3 paddd xmm2,xmm3 130: 66 0f 70 c2 4e pshufd xmm0,xmm2,0x4e 135: 66 0f fe c2 paddd xmm0,xmm2 139: 66 0f 70 c8 e5 pshufd xmm1,xmm0,0xe5 13e: 66 0f fe c8 paddd xmm1,xmm0 142: 66 0f 7e c8 movd eax,xmm1 146: 39 fa cmp edx,edi 148: 89 d6 mov esi,edx 14a: 74 16 je 162 <byRef+0x162> 14c: 0f 1f 40 00 nop DWORD PTR [rax+0x0] 150: 85 f6 test esi,esi 152: ba 00 00 00 00 mov edx,0x0 157: 0f 4f d1 cmovg edx,ecx 15a: 01 d0 add eax,edx 15c: ff c6 inc esi 15e: 39 f7 cmp edi,esi 160: 75 ee jne 150 <byRef+0x150> 162: c3 ret
あと最適化で消されたくないときは import ldc.attributes;
して @weak
を使うとかけっこう盛りだくさんでよかった。
まとめ?
システムプログラミング言語らしく比較的低レイヤの話が多かった印象。プロダクション事例とかはあまりない気がするが、自分のみるセクションが偏っているだけな気もする。