atomic 注释23:爷模板类 _Atomic_storage<T,size_t> 的浮点爹类 _Atomic_floating<T>、 _Atomic_floating< T& >及其成员函数测试

(63)接着阅读 爷模板类 _Atomic_storage《T , size_t》 的浮点爹类 _Atomic_floating《T》 。适合浮点数的原子运算,就要少一点了

// 浮点类型的原子类型的运算:加减法、+=、-=
template <class _Ty>              // provides atomic floating-point operations
struct _Atomic_floating : _Atomic_storage<_Ty>    // 本模板为浮点类型提供原子操作
{   
    using _Base           = _Atomic_storage<_Ty>; // float  的父类是 _Atomic_storage<float,4>
    using difference_type = _Ty;                  // double 的父类是 _Atomic_storage<float,8>

    using _Base::_Base;

    _Ty fetch_add(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) noexcept
    {
        _Ty _Temp{this->load(memory_order_relaxed)}; 

        // 当本类中存储的值   等于形参1 时,把形参 2 的值存入本类;
        // 当本类中存储的值 不等于形参1 时,把本类中的值写入形参 1 。有点指令 cmpxchg 的语义。
        // 返回值表示形参1 与本类中的值是否相等,是则返回 true。 
        // bool compare_exchange_strong (T& expected,T desired, memory_order order = seq_cst)
        while (!this->compare_exchange_strong(_Temp, _Temp + _Operand, _Order)) {} // keep trying
        
        return _Temp; // 可见,依然是返回原子量的旧值
    }

    _Ty fetch_add(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) volatile noexcept 
    {
        return const_cast<_Atomic_floating*>(this)->fetch_add(_Operand, _Order);
    }

    _Ty fetch_sub(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) noexcept 
    {
        _Ty _Temp{this->load(memory_order_relaxed)};

        while (!this->compare_exchange_strong(_Temp, _Temp - _Operand, _Order)) {} // keep trying
        
        return _Temp; // 可见,依然是返回原子量的旧值
    }

    _Ty fetch_sub(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) volatile noexcept
    {
        return const_cast<_Atomic_floating*>(this)->fetch_sub(_Operand, _Order);
    }

    _Ty operator+=(const _Ty _Operand) noexcept // 返回加法的结果
    {
        return fetch_add(_Operand) + _Operand;
    }

    _Ty operator+=(const _Ty _Operand) volatile noexcept // 返回加法的结果
    {
        return const_cast<_Atomic_floating*>(this)->fetch_add(_Operand) + _Operand;
    }

    _Ty operator-=(const _Ty _Operand) noexcept // 返回减法的结果
    {
        return fetch_sub(_Operand) - _Operand;
    }

    _Ty operator-=(const _Ty _Operand) volatile noexcept // 返回减法的结果
    {
        return const_cast<_Atomic_floating*>(this)->fetch_sub(_Operand) - _Operand;
    }

};

++ 对成员函数的测试结果如下

在这里插入图片描述

++ 以及:

在这里插入图片描述

(64)接着给出 类型 _Atomic_floating《T》 的特化版本 _Atomic_floating《T&》 的 源码与成员函数测试

/* 这些注释说明了数据类性的数据成员是数据,引用类型的数据成员,依然是左值引用
template <class _Ty>   // 对齐sizeof (T);x86堆栈在4字节边界上对齐8字节对象
struct _Atomic_padded { alignas(sizeof(_Ty)) mutable _Ty _Value;  };

template <class _Ty>
struct _Atomic_storage_types { using _TStorage = _Atomic_padded<_Ty>; };

template <class _Ty>
struct _Atomic_storage_types<_Ty&> { using _TStorage = _Ty&; };

template <class _Ty>          
struct _Atomic_storage<_Ty, 4> { typename _Atomic_storage_types<_Ty>::_TStorage _Storage; };
*/
// 浮点类型的原子类型的运算:加减法、+=、-=
template <class _Ty>  // provides atomic floating-point operations
struct _Atomic_floating<_Ty&> : _Atomic_storage<_Ty&>
{   
    using _Base           = _Atomic_storage<_Ty&>;
    using difference_type = _Ty;

    using _Base::_Base;

    _Ty fetch_add(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept
    {
        _Ty _Temp { this->load(memory_order_relaxed) } ;

        // 当本类中存储的值   等于形参1 时,把形参 2 的值存入本类;
        // 当本类中存储的值 不等于形参1 时,把本类中的值写入形参 1 。有点指令 cmpxchg 的语义。
        // 返回值表示形参1 与本类中的值是否相等,是则返回 true。 
        // bool compare_exchange_strong (T& expected,T desired, memory_order order = seq_cst)
        while (!const_cast<_Atomic_floating*>(this)->_Base::compare_exchange_strong( _Temp, 
            _Temp + _Operand, _Order)) { } // keep trying

        return _Temp; // 可见,依然是返回原子量的旧值
    }

    _Ty fetch_sub(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept 
    {
        _Ty _Temp { this->load(memory_order_relaxed) };

        while (!const_cast<_Atomic_floating*>(this)->_Base::compare_exchange_strong( _Temp,
            _Temp - _Operand, _Order)) { } // keep trying

        return _Temp;
    }

    _Ty operator += (const _Ty _Operand) const noexcept  // 返回加法的结果
    {
        return fetch_add(_Operand) + _Operand;
    }

    _Ty operator -= (const _Ty _Operand) const noexcept  // 返回减法的结果
    {
        return fetch_sub(_Operand) - _Operand;
    }
};

++ 测试结果如下:

在这里插入图片描述

(65)

谢谢

【四轴飞行器】非线性三自由度四轴飞行器模拟器研究(Matlab代码实现)内容概要:本文围绕非线性三自由度四轴飞行器模拟器的研究展开,重点介绍了基于Matlab的建模与仿真方法。通过对四轴飞行器的动力学特性进行分析,构建了非线性状态空间模型,并实现了姿态与位置的动态模拟。研究涵盖了飞行器运动方程的建立、控制系统设计及数值仿真验证等环节,突出非线性系统的精确建模与仿真优势,有助于深入理解飞行器在复杂工况下的行为特征。此外,文中还提到了多种配套技术如PID控制、状态估计与路径规划等,展示了Matlab在航空航天仿真中的综合应用能力。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的高校学生、科研人员及从事无人机系统开发的工程技术人员,尤其适合研究生及以上层次的研究者。; 使用场景及目标:①用于四轴飞行器控制系统的设计与验证,支持算法快速原型开发;②作为教学工具帮助理解非线性动力学系统建模与仿真过程;③支撑科研项目中对飞行器姿态控制、轨迹跟踪等问题的深入研究; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注动力学建模与控制模块的实现细节,同时可延伸学习文档中提及的PID控制、状态估计等相关技术内容,以全面提升系统仿真与分析能力。
C++中,`alignas` 和 `std::atomic` 是两个用于不同目的的关键特性,它们分别用于控制内存对齐和实现原子操作。 ### `alignas` 的作用 `alignas` 是 C++11 引入的关键字,用于显式指定变量或型的对齐方式。它确保变量在内存中的起始地址是某个特定值的倍数,从而优化访问性能或满足特定硬件要求。例如,在多线程环境中,为了避免伪共享(false sharing),可以将变量对齐到缓存行大小(通常是 64 字节)。 ```cpp alignas(64) std::atomic<std::size_t&gt; counter; ``` 在上述代码中,`counter` 被强制对齐到 64 字节边界,这可以防止多个线程同时修改相邻的变量时发生缓存行伪共享问题,从而提升性能。 ### `std::atomic` 的作用 `std::atomic` 是 C++11 提供的模板类,用于实现原子操作。它确保对变量的读取、写入或复合操作在多线程环境下是不可分割的,从而避免数据竞争问题。`std::atomic<std::size_t&gt;` 表示一个原子的 `std::size_t` 型变量。 ```cpp std::atomic<std::size_t&gt; counter{0}; counter.fetch_add(1, std::memory_order_relaxed); ``` 上述代码展示了如何使用 `std::atomic` 进行原子加法操作。`std::memory_order_relaxed` 指定了内存顺序,控制操作的同步语义。 ### `alignas(64)` 与 `std::atomic<std::size_t&gt;` 的结合使用 当 `alignas(64)` 与 `std::atomic<std::size_t&gt;` 结合使用时,主要目的是避免多线程环境下的伪共享问题。伪共享是指多个线程访问不同的变量,但由于这些变量位于同一个缓存行中,导致缓存一致性协议频繁触发,影响性能。 ```cpp alignas(64) std::atomic<std::size_t&gt; shared_counter; ``` 通过将 `shared_counter` 对齐到 64 字节,可以确保它独占一个缓存行,从而避免与其他变量发生伪共享。 ### 示例代码 以下是一个完整的示例,展示如何使用 `alignas(64)` 和 `std::atomic<std::size_t&gt;` 来优化多线程计数器: ```cpp #include <iostream> #include <thread> #include <vector> #include <atomic> alignas(64) std::atomic<std::size_t&gt; counter{0}; void increment() { for (int i = 0; i < 100000; ++i) { counter.fetch_add(1, std::memory_order_relaxed); } } int main() { std::vector<std::thread> threads; for (int i = 0; i < 4; ++i) { threads.emplace_back(increment); } for (auto& t : threads) { t.join(); } std::cout << "Final counter value: " << counter.load() << std::endl; return 0; } ``` 在该示例中,`counter` 被对齐到 64 字节,并且使用 `std::atomic<std::size_t&gt;` 确保多线程下的原子性操作。 ### 总结 - `alignas(64)` 用于确保变量独占一个缓存行,避免伪共享。 - `std::atomic<std::size_t&gt;` 用于实现线程安全的原子操作。 - 两者的结合使用可以显著提升多线程程序的性能和可靠性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值