服务实施?

我正在编写一个异步日志记录框架,我有多个线程转储数据。 我开始玩Boost asio,因为它提供了一些简单的方法来执行序列化和订购。 由于我是初学者,我开始使用线程安全(使用boost::mutexboost:condition_variable )circular bounded_buffer(实际上是vector)的设计。

我写了一个简单的基准来测量性能。 基准测试只是一个记录一百万条消息的单线程(将它推入缓冲区),而我的工作线程只会从队列中获取消息以登录到文件/控制台/记录器列表。 (PS互斥和CV的用法是正确的,并且指向消息的指针正在移动,所以从这个角度来看,一切都很好/有效)。

当我改变我的实现,而不是使用boost::asio::io_service并且让一个执行run()的线程执行时,性能确实得到了提高(实际上,它增加了记录的消息数量,而不是降低了我的性能初始简单模型)

以下是我想要澄清的几个问题。

  • 为什么性能改进? (我认为boost::asio::io_service内部实现具有处理程序的线程安全队列,这使得它比我自己的初始简单线程安全队列设计更有效率)。 请注意,我的设计经过了充分的审查,没有任何错误(骨架代码基于已证明的示例),是否有人可以更详细地了解io_service如何实现此目的的内部细节。

  • 第二个有趣的观察是,在线程增加时,我的初始实现性能得到了改善,但是以丢失序列化/排序为代价,但性能随boost :: asio降低(非常轻微)(我认为这是因为我的处理程序正在执行非常简单的任务和上下文切换开销正在下降,我会尝试把更复杂的任务,并发表我的意见后)。

  • 我真的很想知道boost::asio只是用于I / O和网络操作还是我用它来通过线程池执行并行任务(并行)是一种很好的设计方法。 io_service对象只是用于I / O对象(如文档中所写),但我发现它是一种非常有趣的方式,可以帮助我以序列化的方式解决并发任务(不仅仅是I / O或与网络相关的任务)(有时会强制执行使用股线进行排序)。 我很兴奋,并且很好奇为什么基本模型没有执行/缩放以及当我使用boost asio。

  • 结果:(在我只有1个工作线程)

  • 1000任务:两种情况下均为10微秒/任务
  • 10000任务:80微秒(有界缓冲区),10微秒升压
  • 100000任务:250微秒(bounde缓冲区),10微秒升压
  • 知道boost如何解决处理程序的io_service线程安全队列中的线程安全问题(我总是认为在某种级别的实现中他们也必须使用锁和cv)会是很有趣的。


    恐怕我对(1)无能为力,但对于另外两个问题:

    (2)我发现boost::asio体系结构中存在一些非确定性的开销,即数据进入(或发送到IO服务对象)之间的延迟可能会从实际的即时响应到最终的数百毫秒的量级。 我试图量化这个问题,作为我试图解决的关于记录和时间戳RS232数据的另一个问题的一部分,但没有得到任何确定的结果或稳定延迟的方法。 我不会感到惊讶的发现类似的问题存在于上下文切换组件中。

    (3)就异步I / O以外的任务使用boost::asio ,它现在是大多数异步操作的标准工具。 我一直使用boost::asio定时器来执行异步进程,并为其他任务生成超时。 将多个工作线程添加到池中的能力意味着您可以很好地扩展其他异步高负载任务的解决方案。 我在去年编写的最简单和最喜欢的类是一个小型的小型工作者线程类,用于boost::asio IO服务(如果有任何错别字,这是从内存中转录而不是剪切和粘贴的道歉):

    class AsioWorker
    {
    public:
      AsioWorker(boost::asio::io_service * service):
      m_ioService(service), m_terminate(false), m_serviceThread(NULL)
      {
        m_serviceThread = new boost::thread( boost::bind( &AsioWorker::Run, this ) )
      }
      void Run( void )
      {
        while(!m_terminate)
          m_ioService->poll_one();
          mySleep(5); // My own macro for cross-platform millisecond sleep
      }
      ~AsioWorker( void )
      {
        m_terminate = true;
        m_serviceThread->join();
      }
    private:
      bool m_terminate;
      boost::asio::io_service *m_ioService;
      boost::thread *m_serviceThread;
    }
    

    这门课是一个很棒的小玩具,只需根据需要添加new玩具,并在完成后delete一些玩具。 将std::vector<AsioWorker*> m_workerPool到使用boost::asio的设备类中,并且可以进一步包装线程池管理内容。 我一直很想写一个智能池自动管理器,根据时间适当增加线程池,但是我还没有一个项目需要它。

    关于如何满足您对线程安全的好奇心,可以深入了解提升的内容,以确切了解他们如何做他们正在做的事情。 就我个人而言,我总是将大部分提升的东西用于面值,并从过去的经验中认为它在引擎盖下非常优化。


    我还发现boost::asio是一般多核处理引擎的优秀基础架构。 我在很多同步的细粒度任务上测量了它的性能,发现它的性能超过了我使用C ++ 11线程和条件变量编写的“经典”实现。

    它也跑赢TBB,但并不如此。 我深入研究他们的代码,试图找到“秘密”。 我唯一能想到的就是他们的队列是一个经典的链表,而不是一个stl容器。

    asio ,我还不确定asio能够在像Xeon Phi这样的大规模线程架构上进行扩展。 似乎缺少的两件事是:

  • 优先队列和
  • 一个偷工作队列。
  • 我怀疑添加这些功能会降低到TBB的性能水平。

    链接地址: http://www.djcxy.com/p/58417.html

    上一篇: SERVICE Implementation?

    下一篇: How to covert svg to eps in ghostscript