Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
gocon_after_party_osaki.pdf
Search
zaiho
November 22, 2025
Programming
47
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
gocon_after_party_osaki.pdf
zaiho
November 22, 2025
Other Decks in Programming
See All in Programming
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
Next.js: The final boss of Web Performance
guaca
0
260
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
220
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
160
npm との違いを手がかりにGo の依存管理を理解したい
optim
0
570
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.6k
Performance Optimization With LLMs
xleitix
0
110
ChromeでローカルLLM
ryu1013
0
140
パスワード再設定メールのURLについて知っておこう
uyuki234
0
160
Event is what happens
moro
2
840
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
210
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
430
Featured
See All Featured
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
620
Between Models and Reality
mayunak
4
500
Code Reviewing Like a Champion
maltzj
529
40k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
We Are The Robots
honzajavorek
0
400
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
520
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
330
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Agile that works and the tools we love
rasmusluckow
331
22k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
730
Typedesign – Prime Four
hannesfritz
42
3.2k
Transcript
愛⽤PCの不具合から始まった、 Goで体感するメモリの世界 Go Night Talks ‒ After Conference
SPEAKER 株式会社ヤプリ サーバーサイドエンジニア ⼤﨑 敬太 • 24新卒として⼊社 • Yappli CRMの開発に従事
• 最近はPHP多め • 好きな⽔は「財宝」
ゲームを起動しただけなのに • ゲームを起動してプレイするたびにブルースクリーン(Windowsが破壊)
1. パーツの不具合を切り分け a. ❌メモリを交換 b. ❌マザボを交換 c. ❌SSDを交換 d. ❌グラボを交換
2. 操作の切り分け a. ✅ブラウジング b. ✅ベンチマークツール c. ❌ゲーム 原因の切り分け ベンチマークツールも ブラウジングもできるし、 CPUは怪しくなさそうやな ⾃分
1. パーツの不具合を切り分け a. ❌メモリを交換 b. ❌マザボを交換 c. ❌SSDを交換 d. ❌グラボを交換
2. 操作の切り分け a. ✅ブラウジング b. ベンチマークツール c. ❌某FPSゲーム 原因の切り分け ゲームってCPUキャッシュ めっちゃ使うからそれが怪 しいじゃない? 友⼈ ...なるほど?
「CPUキャッシュ」に アクセスしやすいコードを書けば、 CPUが原因であることがわかるのでは...?
ネタバレです 実は「原因」は 不明のままPCは死亡しました😇 (CPU変えたら動作したのでCPUのどっかが悪かったです) そのため、仮説検証のために私が⾏ったことを追っていきたいと思います!
そもそもCPUとかメモリの 仕組みをよくわかってない( ̄▽ ̄;)
CPUとメモリ メイン メモリ 左であればあるほどアクセスは⾼速 L3 コアN L1 L2 コアN L1
L2 CPU
CPUとメモリ • キャッシュライン ◦ 固定の⼤きさの連続した64バイトのメモリセグメント ◦ 1つの変数ではなく、まとまった単位でメインメモリからフェッチ • データアライメント ◦
メモリアクセス⾼速化のための、データの割り当て s := make([]int64, 64) for i := range s { s[i] = int64(i + 1) } fmt.Printf("s0: %p (%d)\n", &s[0], uintptr(unsafe.Pointer(&s[0]))) fmt.Printf("s1: %p (%d)\n", &s[1], uintptr(unsafe.Pointer(&s[1]))) fmt.Printf("s2: %p (%d)\n", &s[2], uintptr(unsafe.Pointer(&s[2]))) fmt.Printf("s3: %p (%d)\n", &s[3], uintptr(unsafe.Pointer(&s[3]))) // s0: 0x1400011a000 (1374390689792) // s1: 0x1400011a008 (1374390689800) // s2: 0x1400011a010 (1374390689808) // s3: 0x1400011a018 (1374390689816) s[0] s[1] s[2] s[3]
CPUとメモリ - 寄り道 - • データアライメント ◦ 型によってはパディングが発⽣する type Book
struct { id int32 enable bool title string author string sealed bool publisher string } // Size: 64 実は末尾に 余裕がある type Book struct { title string author string publisher string id int32 enable bool sealed bool } // Size: 56 type Book struct { title string author string publisher string id int32 enable bool sealed bool bool1 bool bool2 bool } // Size: 56 最適化
検証⽅針 • 隙間なくキャッシュラインに格納できるスライスを⽤意! ◦ パディングを発⽣させない • 無限ループで参照しまくるように! • いざ参らん!!! package
main import ( "fmt" "runtime" "sync/atomic" "time" "unsafe" ) type CacheLineData struct { val0 int64 val1 int64 val2 int64 val3 int64 val4 int64 val5 int64 val6 int64 val7 int64 } func printMemStats(label string) { var m runtime.MemStats runtime.ReadMemStats(&m) fmt.Printf("\n=== %s ===\n", label) fmt.Printf("Alloc = %v MiB", m.Alloc/1024/1024) fmt.Printf("\tTotalAlloc = %v MiB", m.TotalAlloc/1024/1024) fmt.Printf("\tSys = %v MiB", m.Sys/1024/1024) fmt.Printf("\tNumGC = %v\n", m.NumGC) } func main() { fmt.Printf("CacheLineData size: %d bytes\n", unsafe.Sizeof(CacheLineData{})) const sliceSize = 512 data := make([]CacheLineData, sliceSize) printMemStats("スライス確保後") // 初期化 for i := range data { data[i].val0 = int64(i) data[i].val1 = int64(i * 2) data[i].val2 = int64(i * 3) data[i].val3 = int64(i * 4) data[i].val4 = int64(i * 5) data[i].val5 = int64(i * 6) data[i].val6 = int64(i * 7) data[i].val7 = int64(i * 8) } printMemStats("初期化後") var iterations atomic.Uint64 ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() fmt.Println("\nL1キャッシュアクセスループ開始 (Ctrl+Cで停止)") go func() { for { <-ticker.C count := iterations.Swap(0) fmt.Printf("Iterations: %d million (avg: %d M/sec)\n", count/1_000_000, count/1_000_000) printMemStats("実行中") } }() var sum int64 for { for i := range data { sum += data[i].val0 sum += data[i].val1 sum += data[i].val2 sum += data[i].val3 sum += data[i].val4 sum += data[i].val5 sum += data[i].val6 sum += data[i].val7 } iterations.Add(1) fmt.Println(sum) } }
• WindowsのインストールUSBをbootに コードをぶん回すゾォ!
まとめ • 学び ◦ メモリの仕組み ▪ まだまだCPUやメモリは不思議がたくさん ◦ メモリを意識したGo ▪
データアライメント ◦ 計測ツール ▪ pprof ▪ -bench, -gcflags PCが壊れたことがきっかけで普段、意識していない領域に触れられた 今後さらに知⾒を深めることで業務に活かしたい