0%

Key Numbers Every Programmer Should Know

本文整理了作为程序员应该知道的关键数字,封面图源自 伯克利每年更新的动态图表 ,可视化的展示了每年各种操作的耗时变化,非常形象。

Key Numbers

数据变化

这里是 2020 年的具体数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
           1   ns - CPU L1 CACHE reference
1 ns - speed-of-light (a photon) travel a 1 ft (30.5cm) distance
3 ns - CPU L1 CACHE Branch mispredict
4 ns - CPU L2 CACHE reference
17 ns - MUTEX lock/unlock
44 ns - Send 2K bytes over Commodity NETWORK
71 ns - CPU cross-QPI/NUMA best case on XEON E5-46*
100 ns - own DDR MEMORY reference
135 ns - CPU cross-QPI/NUMA best case on XEON E7-*
202 ns - CPU cross-QPI/NUMA worst case on XEON E7-*
325 ns - CPU cross-QPI/NUMA worst case on XEON E5-46*
2,000 ns - Compress 1K bytes with Zippy PROCESS
3,000 ns - Read 1 MB sequentially from MEMORY
49,000 ns - Read 1 MB sequentially from SSD
825,000 ns - Read 1 MB sequentially from DISK
500,000 ns - Round trip within a same DataCenter
2,000,000 ns - DISK seek
150,000,000 ns - Send a NETWORK packet CA -> Netherlands
| | | |
| | | ns|
| | us|
| ms|

根据伯克利每年的数据,可以总结出:

  • 从 2005 年后数据有所减少,但是基本稳定的有
    • L1 和 L2 的缓存访问稳定在 ns 量级
    • 互斥锁的代价稳定在 17 ns 量级(关于互斥锁的代价,以后可以专门讨论
    • 访问本地内存的代价基本稳定在 100 ns
    • 同一个数据中心的 RTT 稳定在 500 us
    • 从加州到荷兰的 RTT 稳定在 150 ms
1
2
3
4
5
6
    1 ns        L1 cache
3 ns Branch mispredict
4 ns L2 cache
17 ns Mutex lock/unlock
100 ns Main memory (RAM)
2 000 ns (2µs) 1KB Zippy-compress
  • 还有很多性能现在获得巨大的改善
    • 通过网络发送 2KB 数据损耗的时间,从 05 年的 8000ns 改善到现在的 44ns
    • 从内存顺序读出 1MB 数据损耗的时间,从 05 年的 95,000 ns 改善到现在 3,000 ns
    • 从 SSD 顺序读出 1MB 数据损耗的时间,从 05 年的 2,000,000 ns 改善到现在 49,000 ns,也就是从 2ms 优化到 50us 量级
    • 从磁盘顺序读出 1MB 数据损耗的时间,从 05 年的 7,000,000 ns 改善到现在 825,000 ns,也就是从 7ms 优化到 800us 量级

数据理解

下面从定性角度来理解这些数据。

内存SSD磁盘网络 之间速度的巨大差别了,粗略地讲:

  • SSD比内存慢 10 倍
  • 磁盘比内存慢 300 倍,比 SSD 慢 30 倍
  • 网络比内存慢 10 万倍,比硬盘慢 200 倍

Clock

最开始为了提高计算机速度,选择将 CPU 的频率提高,后来计算机的频率到达 3GHz 之后,很难再提高了,所以访问 Cache 和内存的速度也基本不再变化了。

1
2
3
4
5
6
7
8
9
10
11
12
Core i7 Xeon 5500 Series Data Source Latency (approximate)               [Pg. 22]

local L1 CACHE hit, ~4 cycles ( 2.1 - 1.2 ns )
local L2 CACHE hit, ~10 cycles ( 5.3 - 3.0 ns )
local L3 CACHE hit, line unshared ~40 cycles ( 21.4 - 12.0 ns )
local L3 CACHE hit, shared line in another core ~65 cycles ( 34.8 - 19.5 ns )
local L3 CACHE hit, modified in another core ~75 cycles ( 40.2 - 22.5 ns )

remote L3 CACHE (Ref: Fig.1 [Pg. 5]) ~100-300 cycles ( 160.7 - 30.0 ns )

local DRAM ~60 ns
remote DRAM ~100 ns

NIC

网卡的速度越来越快,从最早的万兆网卡,到现在100Gb的网卡。

网络带宽越大,传输延时越小。

RTT

roundtrip in same datacenter 和 packet roundtrip CA to Netherlands 耗时没有任何变化,一致保持 500us 和 150ms,原因很好理解,毕竟信号在光纤中以近似光速传播,该时间由物理规律决定,这里说的是传播延时

SSD

SSD 的随机读取速度从 1990 年到 2019 年变化不同,不过从 19us 提升到 16us,但顺序读取速度却从 50ms 提升到 49us,提升巨大。

DISK

从 2006 年开始,前两列操作的数值不再变化,只有后两列在变化,说明近十年来存储介质的速度有较大提升。

Mutex

Mutex的lock或unlock操作代价是17 ns。(所以加锁解锁的操作不耗费时间,锁的大量竞争才耗费,思路降低锁粒度,每个锁对象只保护一小部分数据)

写的代价是很昂贵的

  • 数据存储是事务型的:写需要磁盘访问
  • 磁盘访问意味着磁盘寻道
  • 拇指法则(经验规则):一次磁盘寻道就往往浪费了10 ms(毫秒)
  • 简单的计算一下: 1s / 10ms = 100 seeks / sec, 也就是1秒磁盘最大寻道次数在100次

所以,根据以上法则,要时刻考虑你的数据大小和数据结构,并且要以批量的思想来做,批量写和批量读。

Reference