Kubernetes
Kubernetes
CPU cache
https://www.toutiao.com/a6776788422771081739s
1package main
2
3import (
4 "fmt"
5 "sync"
6 "sync/atomic"
7 "time"
8)
9
10//根据以上原理,CPU cache 在缓存数据时,并不是以单个字节为单位缓存的,而是以CPU cache line大小为单位缓存,CPU cache line 在一般的 x86 环境下为 64 字节。
11//也就是说,即使从内存读取 1 个字节的数据,也会将邻近的 64 个字节一并缓存至 CPU cache 中。
12//
13//linux 下,可以通过getconf -a | grep CACHE命令获取 cache line 大小。
14//
15//这也是访问数组通常比链表快的原因之一。
16// 一个uint64占 8 个字节
17type Origin struct {
18 a uint64
19 b uint64
20}
21
22type WithPadding struct {
23 a uint64
24 _ [56]byte
25 b uint64
26 _ [56]byte
27}
28
29var num = 1000 * 1000
30
31func OriginParallel() {
32 var v Origin
33
34 var wg sync.WaitGroup
35 wg.Add(2)
36
37 go func() {
38 for i := 0; i < num; i++ {
39 atomic.AddUint64(&v.a, 1)
40 }
41 wg.Done()
42 }()
43
44 go func() {
45 for i := 0; i < num; i++ {
46 atomic.AddUint64(&v.b, 1)
47 }
48 wg.Done()
49 }()
50
51 wg.Wait()
52 _ = v.a + v.b
53}
54
55func WithPaddingParallel() {
56 var v WithPadding
57
58 var wg sync.WaitGroup
59 wg.Add(2)
60
61 go func() {
62 for i := 0; i < num; i++ {
63 atomic.AddUint64(&v.a, 1)
64 }
65 wg.Done()
66 }()
67
68 go func() {
69 for i := 0; i < num; i++ {
70 atomic.AddUint64(&v.b, 1)
71 }
72 wg.Done()
73 }()
74
75 wg.Wait()
76 _ = v.a + v.b
77}
78
79func main() {
80 var b time.Time
81
82 b = time.Now()
83 OriginParallel()
84 fmt.Printf("OriginParallel. Cost=%+v.\n", time.Now().Sub(b))
85
86 b = time.Now()
87 WithPaddingParallel()
88 fmt.Printf("WithPaddingParallel. Cost=%+v.\n", time.Now().Sub(b))
89}
90
标准库中很多 _ 命名的没有意义的变量就是为了这个 runtime/mheap.go