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又称自旋锁,是实现保护共享资源而提出一种锁机制.自旋锁与互斥锁比较类似,都是为了解决对某项资源的互斥使用 无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一 ...
随机推荐
- 不可或缺 Windows Native (2) - C 语言: 常量,变量,基本数据类型
[源码下载] 不可或缺 Windows Native (2) - C 语言: 常量,变量,基本数据类型 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 常量 变量 基本 ...
- 织梦CMS的MVC体系
13年无意中翻看DedeCMS的代码,发现DedeCMS中是有了一个基本MVC框架的,在现有的版本中,主要是应用到了ask.book等模块上. 织梦这个东西,里面很多设计思想是非常优秀的,但整体代码的 ...
- 批量导数据之利器-load data[2016-07-11]
由于天热,中午吃完饭后不再去逛了,感觉这段时间其实也是可以利用起来的,所以决定每天中午积累一些小的知识点.今天中午,先总结一下最近造数据用到手命令,load data. 使用这个命令的起源是因为最近要 ...
- 内存分段 && 缓冲区 && 析构函数
一.内存中的程序: 在进程被载入内存中时,基本上被分成许多小的节,以下是6个主要的节. 低地址 高地 ...
- ASP.NET WebAPI 10 Action的选择(二)
在本系列的第二篇简要的讲述了Action的选择条件本篇深入讲述一下Action选择的过程在上一篇中我们已经讲到了Controller的激活过程中已经说到了设置Controller的Controller ...
- SharePoint 2013 新功能探索 之 列表等级设置
一.列表等级及赞功能 ,在SharePoint 2010 中,对列表的等级设定,需要一定时间才能看到,现在可以实时同步,评分人数也能显示出来 等级分为两类 赞和星级评定
- jQuery eislideshow 图片轮播
在线实例 基础演示 自动播放 使用方法 <div id="ei-slider" class="ei-slider"> <ul class=&q ...
- CSS之浮动那些事
1.清除浮动 下面是两种常用的方式,而这两招也够用了(不用千招会,只需一招精). 1.结尾处加空div标签 clear:both <style type="text/css" ...
- CRM 2013 Reporting Extensions for SSRS 安装及问题解决
说明一下 Reporting Extensions for SSRS 安装过程. 安装目录在安装目录下 SrsDataConnector 下.如果是CRM 2013安装中运行,可以跳过此步. 此外在说 ...
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q45-Q47)
Question45You create and deploy a custom Web Part.You add the Web Part to a page and receive a run-t ...