在多核环境中选择v / s多线程

时间:2011-12-21 14:34:12

标签: c++ performance unix network-programming

我正在编写一个适用于3层的应用程序。每个层都有多个实例并形成网状关系。

EG。让我们考虑Matrix类型的情况:

                     L11 L12

                 L21 L22 L23 L24

                    L31 L32 L33
  

L11与L21,L22,L23,L24连接   L21与L21,L22,L23,L24连接   L21与L11,L12,L31,L32,L33 ......等连接

目前我正在使用UNIX域套接字与select call进行通信(以确定数据的来源)。 select select上的超时如何影响CPU使用率?

每个连接生成一个新线程或使用select模型持久化会更好吗?通常,L1处的水平可伸缩性可以是大约5,L2将是大约5,L3大约是10。

如果传递给select的位字段很高,那么选择系统调用是否会受到惩罚? 在多线程应用程序的情况下是否使用阻塞系统套接字或非阻塞?

UNIX-Domain套接字中的UDP / TCP是否存在差异?

  

注意:我将使用12-24个内核的系统......可能这就是让我想到为什么不使用单独的线程而不选择调用...

     

注2:Unix域套接字中是否会出现缓冲区溢出?如   就我读到的这些都是无损的而且无序......

1 个答案:

答案 0 :(得分:2)

  

我正在编写一个适用于3层的应用程序。每个层都有多个实例并形成网状关系。

Matrix中的所有节点是在同一主机上运行,​​还是在网络上的多台主机上运行?

  

select select上的超时如何影响CPU使用率?

只有以明显的方式,每次你的select()调用超时,你将不得不去另一个(否则可以避免)旋转你的事件循环。因此,例如,总是传递零(或接近零)的超时将是不好的,因为那样你的线程将浪费CPU周期忙循环。但偶尔的超时应该不是问题。我的建议是尽可能纯粹基于事件,并且只有在不可避免时才使用超时(例如,因为这样的事件必须在特定时间发生,与任何I / O流量无关)。 / p>

  

每个连接生成一个新线程或使用select模型持久化会更好吗?通常,L1处的水平可伸缩性可以是大约5,L2将是大约5,L3大约是10。

对于这种操作规模(几十个连接但不是几百个),select()将正常工作。只有当你遇到数百或数千个连接时,select()开始倒下,即便如此,你也可以转向kqueue()或epoll()而不是多线程。

  

如果传递给select的位字段为高,那么选择系统调用是否会受到惩罚?

我不是100%肯定你的意思是“位字段很高”,但如果你的意思是“指定了很多套接字”,那么主要的好处是select()只适用于其文件描述符整数值小于FD_SETSIZE(通常为1024) - 这意味着select()一次也不能跟踪多个FD_SETSIZE套接字。 (例外:在Windows下,select()将处理具有任意整数值的套接字,尽管它一次不会处理超过FD_SETSIZE套接字的次数)

  

对于多线程应用程序,是使用阻塞系统套接字还是非阻塞?

如果是我,即使在多线程应用程序中,我仍然会使用非阻塞I / O,因为阻塞I / O会使某些事情像应用程序的干净关闭有问题。例如,如果你有一个在recv()中被阻塞的线程,你如何安全地让该线程退出以便你可以清理任何共享资源?您不能发送信号,因为您不知道哪个线程会接收它,并且您不能依赖recv()在有限的时间内自然返回。另一方面,如果你的目标线程只在select()内阻塞,你可以在其中一个FD上发送一个字节,然后选择它()将其唤醒并告诉它消失。

  

UNIX-Domain套接字中的UDP / TCP是否存在差异?

Unix-Domain套接字不使用UDP或TCP(因为它们从不通过网络)。但它们确实使用了SOCK_STREAM和SOCK_DGRAM,它们在使用TCP和UDP套接字到localhost时的行为类似(在大多数方面)。

  

注意:我将使用12-24个内核的系统......可能这就是让我想到为什么不使用单独的线程而不选择调用...

要问自己的问题是,您的应用程序是否可能受计算限制或I / O限制?如果它是计算限制的(并且计算可以并行化),那么您可以将计算转移到多个线程中。如果是I / O绑定,OTOH,多线程没有任何优势,因为在这种情况下,瓶颈很可能是你的网卡(和/或网络本身),你的千兆以太网插孔仍然是无论是一个线程还是多个线程,它都将发送最大1Gb /秒的速率。如果你所有的通信都与同一主机上的其他进程OTOH有关,那么多线程可能会有一些好处,但我的猜测是它会很小,因为看起来你已经在使用所有内核了或者你拥有的流程。

  

注2:Unix域套接字中是否会出现缓冲区溢出?据我所知,这些都是无损的,并且无序......

不应该。 SOCK_STREAM根据我的经验,Unix域套接字的工作方式与TCP套接字非常相似。 (我从未使用过SOCK_DGRAM Unix域套接字,但我认为它们的行为与UDP套接字类似,甚至会丢弃数据包,例如当接收过程无法跟上发送者时)