cpu上下文切换
- 当前线程执行任务的时间片用完,cpu正常调度下一个任务
- 当前线层执行任务遇到IO阻塞,调度器挂起当前任务,调度下一任务
- 当前任务未获取到锁,被调度器挂起
- 用户代码挂起当前任务,让出cpu时间片
- 硬件中断
cpu缓存
cpu拥有三级缓存:L1,L2,L3,级数约小约靠近cpu,访问速度越快;数据访问:L1->L2->L3->Mermory
- L1是最接近cpu的, 它容量最小, 例如32K, 速度最快,每个核上都有一个L1 Cache
- L2 Cache 更大一些,例如256K, 速度要慢一些, 一般情况下每个核上都有一个独立的L2 Cache
- L3 Cache是三级缓存中最大的一级,例如12MB,同时也是最慢的一级, 在同一个CPU插槽之间的核共享一个L3 Cache
伪共享
MESI协议
- M(modified):本地处理器修改了该缓存行,本都缓存数据与内存数据不一致
- E(exclusive):缓存行数据和内存一致,但是其它处理器没有该行数据
- S(share):缓存行与内存数据一致且可能每个处理器数据均一致
- I(invalid):缓存失效,不能使用
RFO
Request For Owner请求将当前数据的权限占有,其它处理器该数据缓存行设置为I。
- 线程从a处理器移到b处理器,相应的缓存行会copy到b处理器上,此时如果线程对缓存数据操作,需要发送RFO请求
- 两个不同处理器操作同一个缓存行
一个线程在处理器a上操作x的值,另一个线程在b处理器上操作y的值,但是x,y的值在同一个缓存行上,这两个线程就会轮番发送RFO请求获得该缓存行的权限操作数据;a处理器上的线程更新x的值时b处理器上的线程会将该缓存行设置成I状态,b处理器上的线程更新y的值时a处理器上的线程会将该缓存行设置成I状态,频繁的RFO请求;此时如果有线程要获取该缓存行的值L1,L2都是失效的,只能从L3共享的缓存获取,如果是跨槽读取,L3读取不到则读取内存;表面上x,y的值是被独立的两个线程操作的,但是他们共享一个缓存行,竞争资源来源于共享。