【精通内核】CPU控制并发原理(六)

307 阅读3分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第8篇文章,点击查看活动详情image.png  

前言

📫作者简介: 小明java问道之路,专注于研究计算机底层/Java/Liunx 内核,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计📫 

🏆 CSDN专家博主/Java优质创作者/CSDN内容合伙人、InfoQ签约作者、阿里云签约专家博主、华为云专家、51CTO专家/TOP红人 🏆

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~

本文导读

本文讲解CPU角度的中断控制,CPU层面并行并发和中断控制的原理,现代CPU的缓存结构和架构图、CPU缓存一致性的源码原理,以及CPU如何通过编译器的屏障与指令实现系统屏障,经过内联汇编代码验证之后,证明上述所说的 Linux 内核用 volatile 关键字实现系统屏障(指令重排),加深对系统屏障的内核源码和原理的理解。

一、指令级屏障

在上述内容已详细介绍了发生指令集排序是由于 CPU 指令流水线造成的,那么有没有办法在处理器中禁止发生重排序呢?我们来看看 Linux 内核源码。

#define mb() alternative("lock;  addl $0,0(%%esp)","mfence", X86_FEATURE_XMM2)

#define rmb() alternative("lock; addl $0,0(%%esp)","lfence", X86_FEATURE_XMM2)

很简单,这里先解释 alternative 宏定义,这是一个选择宏,通过让 CPU 在运行时,根据自己支持的指令集选择并调用相应的指令,所以起到指令重排序作用的指令为 "lock; addl $0, 0(%%esp)", "mfence" 。其中 "mfence" 为新的指令,因为在 intel 之前的 CPU 可以通过 lock 前缀对栈上指令加0操作来作为指令屏障,但后面新出了 mfence和lfence,其中sfence保证了全屏障、读屏障和写屏障的功能;而 "lock; addl S0,0(%%esp)" 指令对于任何 x86 平台都支持,所以这里通过 alternative 宏定义让 CPU 来选择执行哪个。

至于这里的 mfence、lfence、sfence 这里就不进行详述,因为屏障阻止的就是 loadload、storeload、storestore、loadstore 等重排序,这3个指令也是针对这些不同的场景来选择使用的。读者现在只需要记住能通过这几个指令提供 CPU指令集屏障即可,不用深究,否则容易陷入泥潭。

总结

本文讲解CPU角度的中断控制,CPU层面并行并发和中断控制的原理,现代CPU的缓存结构和架构图、CPU缓存一致性的源码原理,以及CPU如何通过编译器的屏障与指令实现系统屏障,经过内联汇编代码验证之后,证明上述所说的 Linux 内核用 volatile 关键字实现系统屏障(指令重排),加深对系统屏障的内核源码和原理的理解。