不可分割的原子操作——《RISC-V体系结构编程与实践 》读书笔记
[复制链接]
不可分割的原子操作——《RISC-V体系结构编程与实践 》读书笔记
原子操作无论在软件设计中中,还是硬件设计中都有所涉及。什么是原子操作呢?原子操作是指“保证指令以原子的方式执行,执行过程不会被打断。”名词解释总是如此地晦涩难懂!
咱们的处理器工作都是以“加载-执行”的模式运行。因此,对数据的操作也就分为了“读-改-写”三步,即将数据从内存中读出来到寄存器,对寄存器中的数据进行运算,处理,再将新数据写回内存的三步。因此,上述三步只要有一步被打断,则新数据就很难保证正确,系统稳定性则很保证。
如何解决呢?要依靠处理器提供硬件支持。RISC-V指令集的A扩展指令集提供两种方式:一是经典的LR和SC指令,部分参考资料也称其为LL/SC指令;另一种是原子内存访问指令。
LL是load-link的缩写,其在内存地址读取一个值,处理器会监控这个内存地址。对于RISC-V来说,它会注册一个保留集。
SC是Store-conditional的缩写,其会监测store指令的执行结果。如果执行失败了,需要跳转到LR指令处,重新执行原子加载以及原子存储操作,但不管结果如何,保留集中的数据都会失效。
RISC-V手册中并未约定LL/SC指令的实现,各个芯片设计厂商可以自由发挥。而对于原子内存访问操作指令,RISC-V指令集,它允许在靠近数据的地方原子地实现“读-改-写”操作,其汇编格式如下:
amo <op>, w/d rd, rs2, (rs1)
举个例子,用AMOADD指令实现atomic_add()函数:
void atomic_add(int i, unsigned long *p){
unsigned long result;
asm volatile("# atomic_add\n"
"amoadd.d %[result], %[i], (%[p])\n"
:[result]"=&r"(result),[p]"+r"(p)
:[i]"r"(i)
:"memory");
}
还有其它利用汇编语言实现的原子操作,如amomax,cmpxchg()函数等。
文中还有一个使用cmpxchg()函数实现的无锁链表,这个挺有意义的,但限于片幅,大家还是购买图片自行查阅吧!嘿嘿
|