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);
}
また、以下のコードはポインタでなく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
を使うとかけっこう盛りだくさんでよかった。
まとめ?
システムプログラミング言語らしく比較的低レイヤの話が多かった印象。プロダクション事例とかはあまりない気がするが、自分のみるセクションが偏っているだけな気もする。