Slide 1

Slide 1 text

リンカを変えてgo buildを 速く出来るか hatena.go #1 Jan. 31 2024 - nasa © 2024 Wantedly, Inc.

Slide 2

Slide 2 text

今日話すこと ● 速いリンカに切り替えるモチベーション ● リンカとは ● moldの紹介 ● 任意のリンカをgolangのビルドに利用する方法 ● golangのリンカを高速リンカmoldに変更してみた結果 © 2024 Wantedly, Inc.

Slide 3

Slide 3 text

モチベーション なぜより速いリンカが欲しいのか ● コンパイル時間を減らしたいから ● goは差分コンパイル ● なのですべてが再コンパイルされるわけじゃないがリンクは毎回実行される ● リンク時間が短くなれば試行回数が増やせる © 2024 Wantedly, Inc.

Slide 4

Slide 4 text

リンカとは プログラムの断片をつなぎ合わせ実行ファイルを作る © 2024 Wantedly, Inc. 引用元: https://speakerdeck.com/nasa_desu/rogukaraxue-bugo-build

Slide 5

Slide 5 text

moldとは © 2024 Wantedly, Inc. Rui Ueyama さんが開発してる高速リンカ 引用元: https://github.com/rui314/mold/blob/main/docs/comparison.png

Slide 6

Slide 6 text

任意のリンカを利用する © 2024 Wantedly, Inc.

Slide 7

Slide 7 text

内部リンカ・外部リンカ ● 内部リンカ、外部リンカのどちらかでリンクされる ● 内部リンカ ○ golang用にスクラッチで実装されたものが内部リンカ ● 外部リンカ ○ clang, GCCなど © 2024 Wantedly, Inc.

Slide 8

Slide 8 text

内部リンカ・外部リンカ ● なぜ2つを使い分けるのか ○ internal linkerだけではリンクできない状況が存在する ○ 具体的な条件は分からなかった。。。 ○ 詳しい人が居たら教えてください ○ CGOが絡むと外部リンカを使っているっぽい © 2024 Wantedly, Inc.

Slide 9

Slide 9 text

任意の外部リンカを使う © 2024 Wantedly, Inc. ● 右図が全体像 ○ 1. go build ○ 2. go tool link ○ 3. external linker(frontend) ○ 4. linker

Slide 10

Slide 10 text

任意の外部リンカを使う © 2024 Wantedly, Inc. ● go buildからgo tool linkを呼んでる ● `ldflags`オプションでlinkコマンドのフラグ指定 ● linkmodeでリンカ内部リンカ・外部リンカのどちらを使 用するか決める $ go build -ldflags="-linkmode=external

Slide 11

Slide 11 text

任意の外部リンカを使う © 2024 Wantedly, Inc. ● extldflagsでコンパイラで外部リンカに任意のフラグを 渡せる ● gccでは`-fuse-ld`でリンカを指定できる $ go build -ldflags="-linkmode=external -extldflags=-fuse-ld=mold -extld=gcc"

Slide 12

Slide 12 text

任意の外部リンカを使う © 2024 Wantedly, Inc. go build → go tool link → gcc → 任意のリンカという依存関係

Slide 13

Slide 13 text

どのリンカが速いのか計測 © 2024 Wantedly, Inc.

Slide 14

Slide 14 text

環境 © 2024 Wantedly, Inc. ● 実行環境 ○ AWS EC2 ○ インスタンスタイプ: c5.xlarge ○ CPU: 4 ○ Memory: 8GiB

Slide 15

Slide 15 text

環境 © 2024 Wantedly, Inc. ● versions ○ go1.21.4 linux/amd64 ○ gcc 11.4.0 ○ lld 14.0.0 ○ gold 1.16 ○ mold 2.4.0

Slide 16

Slide 16 text

環境 © 2024 Wantedly, Inc. ● 計測方法 ○ go build -x -workで必要なファイルを生成 + linkコマンドを把握 ○ -x: go tool linkコマンドがログに出るのでメモる ○ -work: 中間結果を保存する ● /usr/local/go/pkg/tool/linux_amd64/linkを実行 ● この時間を計測した(10回の平均)

Slide 17

Slide 17 text

計測結果 internal gold lld mold hello world 179ms 274ms 370ms 271ms k9s 4.5s 7.3s 5.5s 5.4s jujud 11.6s 17.4s 14.3s 14.9s © 2024 Wantedly, Inc. ※ k8sの誤字ではないです

Slide 18

Slide 18 text

計測結果 internal linkerが一番速い 代替のリンカはまだ無いみたい © 2024 Wantedly, Inc.

Slide 19

Slide 19 text

計測結果 internal lld mold hello world 179ms 370ms 271ms k9s 4.5s 5.5s 5.4s jujud 11.6s 14.3s 14.9s © 2024 Wantedly, Inc. ところでinternalとmoldで2,4秒もの差が出るんだろう?

Slide 20

Slide 20 text

続・リンカを変えてgo buildを速 く出来るか © 2024 Wantedly, Inc.

Slide 21

Slide 21 text

whoami © 2024 Wantedly, Inc. nasa (Asan Kondo) ● Wantedly, Inc. (2021-04-) ○ 推薦基盤チーム ○ Backend中心にあれこれやってる ● ハンドルネームnasaを追い求める民 ○ X(Twitter): @nasa_desu ○ GitHub: @k-nasa

Slide 22

Slide 22 text

we are めっちゃ hiring © 2024 Wantedly, Inc.