x86指令集中lock前缀的意义

简介: 接上篇(https://yq.aliyun.com/articles/59019),对一个变量进行加法操作,可以是3条指令,也可以是1条指令。区别在于,1条指令属于原子操作,不会被打断,那是不是只要1条指令的形式,多线程之间就不需要加锁了呢?我们先试试看。 #include

接上篇(https://yq.aliyun.com/articles/59019 ),对一个变量进行加法操作,可以是3条指令,也可以是1条指令。区别在于,1条指令属于原子操作,不会被打断,那是不是只要1条指令的形式,多线程之间就不需要加锁了呢?我们先试试看。(以下代码仅适用于x86平台,gcc编译器)

#include <stdio.h>
#include <pthread.h>

int count = 0;

void *add(void *arg)
{
    int i;

    for (i = 0; i< 10000; i++) {
        asm(
            "addl $1, %0 \n"
            : : "m"(count) : );
    }
}

int main(int argc, char *argv[])
{
    pthread_t t1, t2;

    pthread_create(&t1, NULL, add, NULL);
    pthread_create(&t2, NULL, add, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("%d\n", count);
    return 0;
}

然后运行:
images51

这是在一个多核处理器且支持对称多处理的系统上运行的结果。可见很大概率上,仍然存在同步问题。那为什么某些情况又能得到20000这个正确结果呢?鬼才知道,只能靠瞎猜。

多核多线程情况下,即便修改操作是单条指令,由于存在并发运行,也不能保证其原子性。幸好有taskset这个程序,可以设置cpu亲和性,我们先将其设置到单核试试看。

images52

嗯貌似完美。

那如果亲和性设置成两个核心呢?

images53

果然,有一定概率出现同步问题。

好了,文章要结束了,总得回到标题,类似电影要到时间了,反派再强大,也得找个方式被灭掉。lock前缀的意义在于,在多核且支持对称多处理的系统上,对于接下来的那条指令,能够保证其原子性。注意lock并不是能够往各个指令面前加的。至于如何保证了原子性,鬼才知道。

我们把add函数改写下:

  for (i = 0; i< 10000; i++) {
        asm(
            "lock \n"
            "addl $1, %0 \n"
            : : "m"(count) : );
    }

再运行几遍:

images54

好了,像是那么回事了。

目录
相关文章
|
Web App开发 存储 缓存
RDMA优化整理(一)
简要的介绍了下RDMA的背景,并给出了一些RDMA编程优化技巧
4475 1
RDMA优化整理(一)
|
编译器 C语言 C++
【C语言】malloc()函数详解(动态内存开辟函数)
【C语言】malloc()函数详解(动态内存开辟函数)
3022 2
|
Linux C++ Windows
linux ln链接命令
linux ln链接命令
2799 0
|
存储 缓存 安全
API接口设计规范
这个是目前第三方数据接口交互过程中常用的一些参数与使用示例,希望对大家有点帮助。 当然如果为了保证更加的安全,可以加上RSA,RSA2,AES等等加密方式,保证了数据的更加的安全,但是唯一的缺点是加密与解密比较耗费CPU的资源.
|
运维 NoSQL Ubuntu
深入理解Linux中的"crash"命令:内核崩溃的调试利器
`crash`是Linux内核崩溃调试工具,用于分析内核崩溃转储文件,提供GDB-like的交互式CLI。通过加载`vmcore`文件和内核映像,管理员可以查看系统状态、调用栈、内存布局等。安装`crash`可使用包管理器,如`apt-get`或`yum/dnf`。尽管有学习曲线且依赖转储文件,但`crash`在系统故障排查中极其重要。
|
边缘计算 运维 Cloud Native
阿里云基于云原生的大规模云边协同关键技术及应用荣获浙江省科学技术进步一等奖
11月22日, 2023年度浙江省科学技术奖获奖成果公布,阿里云与浙江大学、支付宝、谐云科技联合完成的基于云原生的大规模云边协同关键技术及应用获得浙江省科学技术进步一等奖。
|
存储 安全 程序员
C/C++中的整数乘法运算与汇编指令MUL和IMUL
C/C++中的整数乘法运算与汇编指令MUL和IMUL
504 0
|
安全 Unix Linux
深入理解 Linux 内核3
深入理解 Linux 内核
329 2
|
安全 Java 编译器
JVM 的 noverify 启动参数
警告的原因为: 你的 JDK 使用了高于 13 的版本,但是你还是使用了-noverify 运行参数。
559 0
|
Ubuntu 应用服务中间件 nginx
docker--导出镜像 save/export、导入镜像 load/import
docker--导出镜像 save/export、导入镜像 load/import
19820 1