在C ++中将数据从一个线程发送到另一个线程的最快方法是什么?

时间:2012-10-22 22:12:57

标签: c++ multithreading low-latency

我尝试过一个实验,我在其中构建了一个简单的Producer / Consumer程序。它们在不同的线程中运行。生产者生成一些数据,消费者在另一个线程中获取数据。我实现的消息传递延迟大约为100纳秒。任何人都可以告诉我这是否合理,或者是否有明显更快的实施?

我没有使用锁...只是简单的内存计数器。我的实验在这里描述:

http://tradexoft.wordpress.com/2012/10/22/how-to-move-data-between-threads-in-100-nanoseconds/

消费者基本上等待计数器递增,然后调用处理程序函数。所以代码真的不多。我仍感到意外,他花了100秒。

消费者看起来像这样:

 void operator()()
    {
      while (true)
      {
        while (w_cnt==r_cnt) {};
        auto rc=process_data(data);
        r_cnt++;
        if (!rc)
          break;
      }
    }

当生产者有数据时,生产者只需增加w_cnt。

有更快的方法吗?

2 个答案:

答案 0 :(得分:6)

我认为你的延迟是操作系统如何安排上下文切换而不是自旋锁本身的产物,我怀疑你可以做很多事情。

但是,您可以使用环形缓冲区一次移动更多数据。如果一个线程写入并且一个线程读取,则可以实现没有锁定的环形缓冲区。基本上它将是相同的自旋锁定方法(等待tailidx != headidx),但生产者可以在切换到消费者之前将多个值输入缓冲区。这应该会改善您的整体延迟(但不是单值延迟)。

答案 1 :(得分:3)

如果您的线程在不同的核心上执行,那么从一个线程“发送消息”到另一个线程的最快方式是write barrier(sfence)

当您写入某个内存位置时,实际上是写入processors write buffer,而不是写入主内存位置。写入缓冲区由处理器周期性地刷新到主存储器。此外,当指令重新排序发生时,写指令可能会延迟。当实际写入主存储器时,高速缓存一致性协议开始起作用并“通知”另一个处理器关于存储器位置更新。之后,另一个处理器使缓存行无效,另一个线程将能够看到您的更改。

存储屏障力处理器以刷新写入缓冲区并禁止指令重新排序,您的程序将能够每秒发送更多消息。