spin lock自旋锁

 2023-09-13 阅读 17 评论 0

摘要:2019独角兽企业重金招聘Python工程师标准>>> 自旋锁 通过cas操作,在大部分情况下可以实现比std::mutex 更高的性能 基本思想是通过原子操作去尝试获取变量的值 所有线程去竞争 该原子变量 性能: spin_lock_init,无竞争情况下 1.spin_lock 16000W 次每

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

自旋锁 通过cas操作,在大部分情况下可以实现比std::mutex 更高的性能

基本思想是通过原子操作去尝试获取变量的值 所有线程去竞争 该原子变量

性能:

spin_lock_init,无竞争情况下

1.spin_lock 16000W 次每秒

2.mutex 2800W次每秒

3.std::atomic<int> 24100W 次每秒

可见 自旋锁性能挺高的

spinlockirqsave?5个线程竞争情况下

1.spin_lock 717W 每秒

2.mutex 509W 每秒

3.atomic<int>  5900W 每秒

高竞争情况下 还是比mutex 性能高

c++自旋锁?011309016da3286af07ee3dd470edd4f8c0.jpg

 

贴上代码

调整原子操作的内存顺序 可以再次加强性能,暂时用默认方式处理把

/*
Email me@dreamyouxi.com自旋锁*/
#pragma  once
#include <atomic>
#include <thread>
#include <chrono>//cas 
class spin_lock
{
private:std::atomic<bool> _internal_tag = false;
private:spin_lock(const spin_lock &) = delete;spin_lock& operator = (const spin_lock&) = delete;
public:void lock();void unlock();
};class spin_lock_guard
{spin_lock & locker;// ref
public:spin_lock_guard(spin_lock& lock);~spin_lock_guard();
};
#include "util/log.h"
#include "concurrency/spin_lock.h"
const char LOG_NAME[] = "spin_lock";
using namespace  std;void spin_lock::lock()
{bool except = false;int times = 0;//fast passwhile (true){if (_internal_tag.compare_exchange_strong(except, true, std::memory_order_seq_cst)){//ok got itreturn;}if (++times > 4000){//break;}except = false;}times = 0;//slow passwhile (true){if (_internal_tag.compare_exchange_strong(except, true, std::memory_order_seq_cst)){//ok got itreturn;}if (++times < 1000){//this_thread::yield();}else{break;}except = false;}// //very slow passwhile (true){if (_internal_tag.compare_exchange_strong(except, true, std::memory_order_seq_cst)){//ok got itreturn;}except = false;//内存延时 6代E5 大概是100纳秒一个周期//mutex 无竞争情况下 性能大概是每秒300W 次 即 0.3微秒 300纳秒//sleep_for 进度在win平台好像最小是1MS 因此这里的设定也许有BUGthis_thread::sleep_for(std::chrono::nanoseconds(300));}
}void  spin_lock::unlock()
{_internal_tag.store(false, std::memory_order_seq_cst);
}spin_lock_guard::spin_lock_guard(spin_lock& lock) :
locker(lock)
{locker.lock();
}spin_lock_guard::~spin_lock_guard()
{locker.unlock();
}

 

自旋锁使用,最高性能版本

/*
Email me@dreamyouxi.com自旋锁*/
#pragma  once
#include <atomic>
#include <thread>
#include <chrono>//cas 
class spin_lock
{std::atomic_flag locker = ATOMIC_FLAG_INIT;  // NOLINT
public:spin_lock(const spin_lock &) = delete;spin_lock& operator = (const spin_lock&) = delete;spin_lock() = default;void unlock(){locker.clear(std::memory_order_release);}void lock();
private:bool try_lock(){bool ok = locker.test_and_set(std::memory_order_acquire);return !ok;}
};class spin_lock_guard
{spin_lock & locker;// ref
public:spin_lock_guard(spin_lock& lock);~spin_lock_guard();
};#include "util/log.h"
#include "concurrency/spin_lock.h"
const char LOG_NAME[] = "spin_lock";
using namespace  std;void spin_lock::lock()
{int times = 0;//fast passwhile (true){if (try_lock()){//ok got itreturn;}if (++times > 4000){//break;}}times = 0;//slow passwhile (true){if (try_lock()){//ok got itreturn;}if (++times < 1000){//this_thread::yield();}else{break;}}// //very slow passwhile (true){if (try_lock()){//ok got itreturn;}//内存延时 6代E5 大概是100纳秒一个周期//mutex 无竞争情况下 性能大概是每秒300W 次 即 0.3微秒 300纳秒//sleep_for 进度在win平台好像最小是1MS 因此这里的设定也许有BUGthis_thread::sleep_for(std::chrono::nanoseconds(300));}
}spin_lock_guard::spin_lock_guard(spin_lock& lock) :
locker(lock)
{locker.lock();
}spin_lock_guard::~spin_lock_guard()
{locker.unlock();
}

 

转载于:https://my.oschina.net/kkkkkkkkkkkkk/blog/2221516

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/50408.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息