linux 内核同步互斥技术之cache 伪共享和隐含内存屏障

2023-12-21 09:52

本文主要是介绍linux 内核同步互斥技术之cache 伪共享和隐含内存屏障,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

隐含内存屏障

内核的有些函数隐含内存屏障。
(1)获取和释放函数。
(2)中断禁止函数。

1.获取和释放函数
获取( acquire)函数包括如下。
(1)获取锁的函数。锁包括自旋锁、读写自旋锁、互斥锁、信号量和读写信号量。
(2) smp_load_acquire(p):加载获取。
(3) smp_cond_load_acquire(ptr, cond_expr):带条件的加载获取。

获取操作隐含如下。
(1)获取操作后面的内存访问操作只能在获取操作完成之后被观察到。
(2)获取操作前面的内存访问操作可能在获取操作完成之后被观察到。

释放(release)函数包括如下。
(1)释放锁的函数。
(2) smp_store_release(p, v):存储释放。

释放操作隐含如下。
(1)释放操作前面的内存访问操作必须在释放操作完成之前被观察到。
(2)释放操作后面的内存访问操作可能在释放操作完成之前被观察到。

获取操作和释放操作都是单向屏障。

有返回值的atomic操作
主要指以下方法:
        xchg();
        cmpxchg();
        atomic_cmpxchg();
        atomic_inc_return();
        atomic_dec_return();
        atomic_add_return();
        atomic_sub_return();
        atomic_inc_and_test();
        atomic_dec_and_test();
        atomic_sub_and_test();
        atomic_add_negative();
        atomic_add_unless();    /* when succeeds (returns 1) */
        test_and_set_bit();
        test_and_clear_bit();
        test_and_change_bit();
而这些方法是不隐含内存屏障的:
        atomic_set();
        set_bit();
        clear_bit();
        change_bit();
        atomic_add();
        atomic_sub();
        atomic_inc();
        atomic_dec();

2.中断禁止函数
禁止中断和开启中断的函数只充当编译器优化屏障。

cache 伪共享

我们熟悉了MESI状态的转换的之后,我们来看cache伪共享就简单多了。什么是cache伪共享呢?其实,我们知道一个cache line的大小是32字节或者64字节,如果两个频繁访问的数据A和B,他们共处在一个cache line里面,然后不同的CPU都在频繁的访问A或者B的数据,那么就会带来性能上的问题,可能这个cache line的状态要频繁的变来变去,造成一种无畏的颠簸,我们知道MESI本质上是要消耗系统内部总线的带宽的,你一个cache line的状态老是频繁的变来变去,总线带宽都被你消耗了不少,当然会引起性能的问题,所以,这个叫做cache伪共享(英文叫做false sharing)。
伪共享的避免:
第一个案例是cache的伪共享的避免。避免的方法主要有两个。
第一个是:一些常用的数据结构在定义时就约定数据结构以一级缓存对齐。例如使用如下的宏来让数据结构首地址以L1 cache对齐。下面这个宏是利用了GCC的特性,_attribute的属性,来让数据结构的起始地址以某个数字对齐,这里是以L1 cache对齐。
  
第二个是:数据结构中频繁访问的成员可以单独占用一个高速缓存行,或者相关的成员在高速缓存行中彼此错开,以提高访问效率。
例如struct zone数据结构使用ZONE_PADDING技术(填充字节的方式)来让频繁访问的成员在不同的cache line中。
  
所以,cache伪共享,在有些情况下是性能杀手,而且你又比较难去发现它,所以需要我们编程的时候,特别注意。你写的数据结构里,有没有可能出现 不同的CPU核心频繁访问某些成员,导致cache伪共享的?这个需要写程序的时候就要思考清楚。
 

这篇关于linux 内核同步互斥技术之cache 伪共享和隐含内存屏障的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/519520

相关文章

MySQL主从同步延迟问题的全面解决方案

《MySQL主从同步延迟问题的全面解决方案》MySQL主从同步延迟是分布式数据库系统中的常见问题,会导致从库读取到过期数据,影响业务一致性,下面我将深入分析延迟原因并提供多层次的解决方案,需要的朋友可... 目录一、同步延迟原因深度分析1.1 主从复制原理回顾1.2 延迟产生的关键环节二、实时监控与诊断方案

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

Linux命令之firewalld的用法

《Linux命令之firewalld的用法》:本文主要介绍Linux命令之firewalld的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux命令之firewalld1、程序包2、启动firewalld3、配置文件4、firewalld规则定义的九大

Linux之计划任务和调度命令at/cron详解

《Linux之计划任务和调度命令at/cron详解》:本文主要介绍Linux之计划任务和调度命令at/cron的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux计划任务和调度命令at/cron一、计划任务二、命令{at}介绍三、命令语法及功能 :at

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt