Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
gocon_after_party_osaki.pdf
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
zaiho
November 22, 2025
Programming
41
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
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
130
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
140
不幸な GC
chencmd
0
890
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
500
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.6k
Can LLMs Replicate 4 Years of Compose Migration? Exploring the boundaries of automation with 279 XML files from a real product
makun
0
130
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
150
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
290
typoなんかねぇよ
raspython3
0
670
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
160
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
170
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
0
140
Featured
See All Featured
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
230
Automating Front-end Workflow
addyosmani
1369
210k
A better future with KSS
kneath
240
18k
Balancing Empowerment & Direction
lara
6
1.3k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
680
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
490
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Code Reviewing Like a Champion
maltzj
528
40k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6.2k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.8k
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が壊れたことがきっかけで普段、意識していない領域に触れられた 今後さらに知⾒を深めることで業務に活かしたい