atomic 注释12:函 __iso_volatile_load32 (),_mm_pause (),_Atomic_lock_acquire (),_Atomic_lock_release ()

(32)函 __iso_volatile_load32 (),顾名思义,该函数是要读取某个变量的值:

在这里插入图片描述
在这里插入图片描述

++ 还是测试一下:

在这里插入图片描述

(33)函数 _mm_pause () , CPU 忙等待时,降低功耗再等待

在这里插入图片描述

++ 以下是一个简单的 C++ 示例,展示了如何在自旋锁中使用 _mm_pause

#include <atomic>
#include <immintrin.h> // 包含 _mm_pause 函数的头文件

std::atomic<bool> lock_flag(false);

void spin_lock() 
{
    while (lock_flag.test_and_set(std::memory_order_acquire)) 
        _mm_pause(); // 在循环中使用 _mm_pause 来降低功耗
}

void spin_unlock() {   lock_flag.clear(std::memory_order_release); }

int main() {
    // 示例用法
    spin_lock();
    // 执行临界区代码
    spin_unlock();
    return 0;
}

(34)全局函数 _Atomic_lock_acquire (),本函数似乎实现了一个 STL 库级别的自旋锁,源代码如下:

在这里插入图片描述

++ 再给个其代码版本,看哪个版本阅读时候更舒服一些:

inline void _Atomic_lock_acquire(_Smtx_t* _Spinlock) noexcept // 重载函数,功能肯定是一样的  
{
    _Smtx_lock_exclusive(_Spinlock);                          // using _Smtx_t = void*;
}

// 本函的语义是让本线程执行忙等待,直到形参的值为 0 才返回。
// 函数名顾名思义:原子性的获取锁。形参就是锁,形参值为0 表示锁空闲。
inline void _Atomic_lock_acquire(long& _Spinlock) noexcept // 本函有删减,仅仅适用于 intel CPU
{
#if defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
    int       _Current_backoff   =  1 ; // 这里是定义了一个偏移量
    const int _Max_backoff       = 64 ; // 随后每次都让 _Current_backoff 的值左移一位,增加 2 倍

    // LONG _InterlockedExchange( LONG volatile* Target, LONG Value ); windows 平台的原子函数
    // 原子性的把形参 2 赋值给形参 1,并返回形参 1 里的旧值。本函数只操作 32 bit 的数据
    while (_InterlockedExchange(&_Spinlock, 1) != 0) // 外层循环只执行一次,自旋锁为 0 则同时结束内外循环
    {   
        // 已知 int a = 3 ; int& b = a; 经测试:对左值引用取地址 &b 返回的是原始变量 a 的地址 
        // uint32_t __iso_volatile_load32(const volatile uint32_t *addr); 从形参地址里原子性的读取一个值
        while (__iso_volatile_load32(&reinterpret_cast<int&>(_Spinlock)) != 0) 
        {
            for (int _Count_down = _Current_backoff; _Count_down != 0; --_Count_down) 
                _mm_pause(); // 此函数是为了让 X86 x64 平台上的 CPU 执行低功耗的、低频率的忙等待 
            
            _Current_backoff = _Current_backoff < _Max_backoff ? _Current_backoff << 1 : _Max_backoff;
        }
    }
#endif
}

++ 测试一下:

在这里插入图片描述

(35) 函数 _Atomic_lock_release () ,本函数与上面的函数是对应的。本函数原子性的释放锁,其实就是拿一个整数值作为标志,来表示临界资源是否空闲

// 顾名思义:这俩函数是原子性的释放锁,赋值形参锁为 0 值。
inline void _Atomic_lock_release(long& _Spinlock) noexcept    // 本函有删减,仅仅适用于 intel CPU
{
#if defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
    _InterlockedExchange(&_Spinlock, 0); 
#endif
}

inline void _Atomic_lock_release(_Smtx_t* _Spinlock) noexcept // 函数重载,32 位版本与 64 位版本
{
    _Smtx_unlock_exclusive(_Spinlock);                        // 上面的函数更容易理解
}

(36)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值