• ACE默认高效实现之自适应锁策略兼谈模板与宏


    问题

    ACE中大量使用锁策略作为模板参数,而它自适应两种策略的代价有多大呢?

    分析

    对于有锁场景,估计代价都差不多。而对于无锁场景,使用ACE影响是几何呢?它还是高效的么?

    ACE经常在实现上使用锁策略作为模板参数,在模板方法实现中也经常使用ACE_MT (ACE_GUARD_* (...))宏方法来实现对锁的使用。

    特别地,ACE提供了ACE_Guard无锁的特化版本的ACE_Guard,以利于使用无锁策略时减少代价。

    由于ACE_Guard大量使用内联方法,且返回值为恒定的常量,所以,在编译高度优化时,这些代码通常会被删减掉,进而,在运行时间是没有代价的,相当于没有加任何锁的代码!

    学习:在此,需要崇拜下模板的元编程和编译器的伟力!

    增强学习: 在某些类中不使用虚函数,将会有内联上的方便

    它山之石

    **《Effective C++》**一书中说道,如果使用STL应尽量了解提供的各种算法,这些算法一般会比手写的排序、循环、或算法要快。

    作者指出一个很重要的原因,就是STL算法模板在编译器的加持下,与STL各组件的充分内联,会比C qsort(...)省去一些不必要的函数调用!

    可见C++更适合大数量处理

    兼谈模板与宏

    我们知道,模板与宏都可以指导编译器生产代码,而且模板生产的代码,将会有更多的编译器检查,所以,应尽量用模板来替代宏!

    但即使在ACE中依然存在大量宏产生代码的场景,为何?

    我想一个重要的原因就是,宏还是有其不可替代的优势!

    例如,宏方法可以直接终止当前调用流程,见ACE_GUARD_RETURN宏方法。这点是模板方法,或模板类无法企及的特性,用模板反而带来代码上的累赘!

    用的恰如其分 😃

    参考

    ACE_Guard宏方法

    #if !defined (ACE_GUARD_ACTION)
    #define ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ACTION, REACTION) \
       ACE_Guard< MUTEX > OBJ (LOCK); \
       if (OBJ.locked () != 0) { ACTION; } \
       else { REACTION; }
    #endif /* !ACE_GUARD_ACTION */
    
    #if !defined (ACE_GUARD_REACTION)
    #define ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, REACTION) \
      ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ;, REACTION)
    #endif /* !ACE_GUARD_REACTION */
    
    #if !defined (ACE_GUARD)
    #define ACE_GUARD(MUTEX, OBJ, LOCK) \
      ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return)
    #endif /* !ACE_GUARD */
    
    #if !defined (ACE_GUARD_RETURN)
    #define ACE_GUARD_RETURN(MUTEX, OBJ, LOCK, RETURN) \
      ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return RETURN)
    #endif /* !ACE_GUARD_RETURN */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    ACE_Guard特化无锁版本

    template<>
    class ACE_Export ACE_Guard<ACE_Null_Mutex>
    {
    public:
      ACE_Guard (ACE_Null_Mutex &) {}
      ACE_Guard (ACE_Null_Mutex &, int) {}
      ACE_Guard (ACE_Null_Mutex &, int, int) {}
    #if defined (ACE_WIN32)
      ~ACE_Guard () = default;
    #endif /* ACE_WIN32 */
    
      int acquire () { return 0; }
      int tryacquire () { return 0; }
      int release () { return 0; }
      void disown () {}
      int locked () { return 1; }
      int remove () { return 0; }
      void dump () const {}
    
    private:
      ACE_Guard (const ACE_Guard<ACE_Null_Mutex> &) = delete;
      void operator= (const ACE_Guard<ACE_Null_Mutex> &) = delete;
      ACE_Guard (ACE_Guard<ACE_Null_Mutex> &&) = delete;
      void operator= (ACE_Guard<ACE_Null_Mutex> &&) = delete;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    最短路径专题8 交通枢纽 (Floyd求最短路 )
    众和策略:小盘和大盘的关系?
    前端开发调试技巧:如何在Component下选中当前插件并且查看当前插件信息
    低代码平台如何兼顾开发速度与开发质量
    面试系列多线程:谈谈线程池的核心参数及工作原理
    STM32全链路开发实战教程专栏总目录
    Android多线程总结
    前端的基本介绍
    SpringBoot对Filter过滤器中的异常进行全局处理
    PPLiteSeg实时语义分割预测结果输出控制无人车转向角度方向实现沿车道无人驾驶
  • 原文地址:https://blog.csdn.net/jkler_doyourself/article/details/132918707