atomic, spinlock and mutex性能比较
1. 无同步的情况
#include <future>
#include <iostream> volatile int value = ; int loop (bool inc, int limit) {
std::cout << "Started " << inc << " " << limit << std::endl;
for (int i = ; i < limit; ++i) {
if (inc) {
++value;
} else {
--value;
}
}
return ;
} int main () {
auto f = std::async (std::launch::async, std::bind(loop, true, ));//开启一个线程来执行loop函数,c++11的高级特性
loop (false, );
f.wait ();
std::cout << value << std::endl;
}
通过clang编译器:
clang++ -std=c++ -stdlib=libc++ -O3 -o test test.cpp && time ./test
运行:
SSttaarrtteedd real 0m0.070s
user 0m0.089s
sys 0m0.002s
从运行结果很显然的我们可以看出增减不是原子性操作的,变量value最后所包含的值是不确定的(垃圾)。
2. 汇编LOCK
#include <future>
#include <iostream> volatile int value = ; int loop (bool inc, int limit) {
std::cout << "Started " << inc << " " << limit << std::endl;
for (int i = ; i < limit; ++i) {
if (inc) {
asm("LOCK");
++value;
} else {
asm("LOCK");
--value;
}
}
return ;
} int main () {
auto f = std::async (std::launch::async, std::bind(loop, true, )); //开启一个线程来执行loop函数,c++11的高级特性
loop (false, );
f.wait ();
std::cout << value << std::endl;
}
SSttaarrtteedd real 0m0.481s
user 0m0.779s
sys 0m0.005s
在最后变量value得到了正确的值,但是这些代码是不可移植的(平台不兼容的),只能在X86体系结构的硬件上运行,而且要想程序能正确运行编译的时候必须使用-O3编译选项。另外,由于编译器会在LOCK指令和增加或者减少指令之间注入其他指令,因此程序很容易出现“illegal instruction”异常从而导致程序被崩溃。
3. 原子操作atomic
#include <future>
#include <iostream>
#include "boost/interprocess/detail/atomic.hpp" using namespace boost::interprocess::ipcdetail; volatile boost::uint32_t value = ; int loop (bool inc, int limit) {
std::cout << "Started " << inc << " " << limit << std::endl;
for (int i = ; i < limit; ++i) {
if (inc) {
atomic_inc32 (&value);
} else {
atomic_dec32 (&value);
}
}
return ;
} int main () {
auto f = std::async (std::launch::async, std::bind (loop, true, ));
loop (false, );
f.wait ();
std::cout << atomic_read32 (&value) << std::endl;
}
运行:
SSttaarrtteedd real 0m0.457s
user 0m0.734s
sys 0m0.004s
最后结果是正确的,从所用时间来看跟汇编LOCK的差不多。当然原子操作的底层也是使用了LOCK汇编来实现的,只不过是使用了可移植的方法而已。
4. 自旋锁spinlock
#include <future>
#include <iostream>
#include "boost/smart_ptr/detail/spinlock.hpp" boost::detail::spinlock lock;
volatile int value = ; int loop (bool inc, int limit) {
std::cout << "Started " << inc << " " << limit << std::endl;
for (int i = ; i < limit; ++i) {
std::lock_guard<boost::detail::spinlock> guard(lock);
if (inc) {
++value;
} else {
--value;
}
}
return ;
} int main () {
auto f = std::async (std::launch::async, std::bind (loop, true, ));
loop (false, );
f.wait ();
std::cout << value << std::endl;
}
运行:
SSttaarrtteedd real 0m0.541s
user 0m0.675s
sys 0m0.089s
最后结果是正确的,从用时来看比上述的慢点,但是并没有慢太多
5. 互斥锁mutex
#include <future>
#include <iostream> std::mutex mutex;
volatile int value = ; int loop (bool inc, int limit) {
std::cout << "Started " << inc << " " << limit << std::endl;
for (int i = ; i < limit; ++i) {
std::lock_guard<std::mutex> guard (mutex);
if (inc) {
++value;
} else {
--value;
}
}
return ;
} int main () {
auto f = std::async (std::launch::async, std::bind(loop, true, ));
loop (false, );
f.wait ();
std::cout << value << std::endl;
}
运行:
SSttaarrtteedd real 0m25.229s
user 0m7.011s
sys 0m22.667s
互斥锁要比前面几种的慢很多
Benchmark
Method Time (sec.)
No synchronization 0.070
LOCK 0.481
Atomic 0.457
Spinlock 0.541
Mutex 22.667
当然,测试结果会依赖于不同的平台和编译器(我是在Mac Air和clang上做的测试)。
原文链接:http://demin.ws/blog/english/2012/05/05/atomic-spinlock-mutex/
atomic, spinlock and mutex性能比较的更多相关文章
- std::atomic和std::mutex区别
std::atomic介绍 模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>.在多线程调用下,利用std::atomic可实 ...
- 内核必看: spinlock、 mutex 以及 semaphore
linux 内核的几种锁介绍 http://wenku.baidu.com/link?url=RdvuOpN3RPiC5aY0fKi2Xqw2MyTnpZwZbE07JriN7raJ_L6Ss8Ru1 ...
- Pthreads并行编程之spin lock与mutex性能对比分析(转)
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API.线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用 ...
- spinlock,mutex,semaphore,critical section的作用与差别
某年深信服的笔试题,考的就是多线程的同步.简单的解释下方便记忆: 1.spinlock:自旋锁.是专为防止多处理器并发而引入的一种锁. 2.mutex:相互排斥量. 仅仅有拥有相互排斥对象的线程才有訪 ...
- Any race is a bug. When there is a race, the compiler is free to do whatever it wants.
https://mp.weixin.qq.com/s/pVJiFdDDKVx707eKL19bjA 谈谈 Golang 中的 Data Race 原创 ms2008 poslua 2019-05-13 ...
- Samsung_tiny4412(驱动笔记07)----spinlock,semaphore,atomic,mutex,completion,interrupt
/*********************************************************************************** * * spinlock,se ...
- 浅谈Unity的渲染优化(1): 性能分析和瓶颈判断(上篇)
http://www.taidous.com/article-667-1.html 前言 首先,这个系列文章做个大致的介绍,题目"浅谈Unity",因为公司和国内大部分3D手游开发 ...
- go sync.Mutex 设计思想与演化过程 (一)
go语言在云计算时代将会如日中天,还抱着.NET不放的人将会被淘汰.学习go语言和.NET完全不一样,它有非常简单的runtime 和 类库.最好的办法就是将整个源代码读一遍,这是我见过最简洁的系统类 ...
- 【linux】spinlock 的实现
一.什么是spinlock spinlock又称自旋锁,是实现保护共享资源而提出一种锁机制.自旋锁与互斥锁比较类似,都是为了解决对某项资源的互斥使用 无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一 ...
随机推荐
- Csharp: read excel file using Open XML SDK 2.5
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Ahjesus Nodejs01 环境搭建及运行
访问http://nodejs.org/,根据系统选择下载文件,我用的win7 64 安装一路下一步直到完成 运行cmd输入node -v查看是否安装成功 成功会显示版本号 到此环境搭建完毕 ==== ...
- 「C语言」int main还是void main?
从大一入学刚接触C到现在已满7个月了,虽然刚开始就知道```int main```才是标准的写法,但一直没有深刻理解为什么不能用```void main```而必须使用```int main```. ...
- C# 循环语句 for循环(嵌套 while 穷举 迭代)
for循环的嵌套类似于if else 事例: 打印矩阵,外循环对应行,内循环对应列 for (int k = 1; k <= 5; k++) { for (int i = 1; i <= ...
- C# 分支语句
选择语句 if,else if是如果的意思,else是另外的意思,if后面跟()括号内为判断条件,如果符合条件则进入if语句执行命令.如果不符合则不进入if语句.else后不用加条件,但是必须与if配 ...
- php对mysql数据库简单连接操作
前些阵子忙完了公司前端静态页面的事情了之后,简单学习了下php的基础知识,今天想了想回顾一下php连接数据库的方式,写一下随笔存一下看看 php连接数据库端口和新建数据库 <?php $serv ...
- CRM2013版本 IOS APP 说明(IPhone、IPad)
CRM2013版本 IOS APP 说明(IPhone.IPad) IPhone版本 首页 CRM APP在登录时输入账号信息,可以进行首面.其首页显示内容可以在CRM后台设置. 系统默认显示:Pho ...
- SharePoint 使用代码为页面添加WebPart
传统的SharePoint实施中,我们通常会创建SharePoint页面,然后添加webpartzone,而后在上面添加webpart:但是有些情况下,也要求我们使用代码,将webpart添加到相应w ...
- SharePoint部署工具SPSD
SharePoint Solution Deployer,绝对属于必备的SharePoint工具之一了. 下载,解压这个工具,会有如下的目录(没有Assemblies和DeployGAC.bat)解压 ...
- File类的常用方法
public static void GetFileInfo() { File file=new File("e:","two.txt ...