2010-02-24 110 views
4

我将在我的server-app中创建x个线程数。 x将是机器上的内核数量,并且这些线程将是(非超线程)内核绑定的。当然,在这个方案中,我希望在线程之间分配传入连接,目的是确保一旦连接被分配给一个线程,它只会被用于特定线程之外。这在boost :: asio中如何实现?boost :: asio:线程本地异步事件

我在想:单个socket绑定到多个io_service共享的地址,其中每个线程都得到它自己的io_service。这一推理是否正确?

编辑:看起来像我将不得不自己回答这个问题。

回答

5

是的,你的推理基本上是正确的。您将为每个线程创建一个线程,为每个线程创建一个io_service实例,并在每个线程中调用io_service.run()。

但问题是你是否真的这样做。这是我看到的问题:

  • 您可以结束了非常繁忙的内核和空闲核心根据工作是如何通过你的连接平衡。微内核中缓存命中的微优化可能意味着,当“最佳”内核没有准备好时,最终会失去让空闲内核工作的能力。

  • 在套接字速度(即:慢),你会从CPU高速缓存命中获得多少胜利?如果一个连接需要足够的CPU来保持内核忙碌,并且只有与内核连接的连接数量很多,那就太棒了。否则,无法移动工作来处理工作负载的变化可能会破坏您从缓存命中中获得的任何胜利。如果你在每个线程中做很多不同的工作,缓存不会太热。

  • 如果你只是在做I/O,无论如何,缓存获胜可能并不那么大。取决于你的实际工作量。

我的建议是有一个io_service实例并在每个核心的线程中调用io_service.run()。如果性能不足或者每个连接有很多CPU的连接类别,并且您可以获得缓存胜利,请将这些连接移至特定的io_service实例。

在这种情况下,您应该进行分析以查看有多少缓存未命中导致您的成本以及在哪里。

+0

很好的回答,很好的推理。我可能会坚持你的建议,直到我看到一个问题 - 很高兴知道如果我选择微观优化是可能的。 – 2010-03-03 09:54:09

2

如果您的服务器应用程序应该在Windows机器上运行,那么您应该考虑使用IO完成端口。

它能够将活动线程的数量限制为内核数量。它将IO事件从理论上无限数量的套接字分发给活动线程。调度由OS完成。 Here是一个很好的例子。

+0

(+1)IO完成端口踢屁股 - 但是,我目前的实现使用IO完成端口和命名管道。我从头开始重写这个东西,可移植性很重要。 – 2010-02-24 10:26:33

+0

+1,这里是链接到您链接到的源代码示例的最新版本的链接:http://www.lenholgate.com/archives/000637.html – 2010-02-26 13:15:15

0

您可以使用多个线程使用的单个io_servicestrand以确保连接始终由同一个线程处理。看看HTTP server 3 example

+0

我的问题比示例提供的更具体/更高级一点。 – 2010-03-03 09:32:31