2010-10-14 156 views
4

我们必须使我们的系统具有高度可扩展性,并且已经针对使用VC++的Windows平台开发。说起初,我们想同时处理100个请求(来自msmq)。最好的方法是什么?单线程100线程或2线程50-50线程?在第二种方法的情况下,除了过程记忆之外还有什么收益。在Windows中首先将CPU时间分配给进程,然后在该进程的线程之间进行拆分,或者OS对每个进程的线程数进行计数并根据线程而不是进程分配CPU。我们注意到,在第一种情况下,CPU利用率是15-25%,我们想要消耗更多的CPU。请记住,我们希望获得最佳性能,因此100个请求只是例如。我们也注意到,如果我们增加120以上进程的线程数,由于上下文切换性能下降。Windows,多进程vs多线程

还有一点;我们的产品已经支持群集,但我们希望在单个节点上使用更多的CPU。

任何建议将不胜感激。

回答

3

windows上的标准方法是多线程。并不是说这总是你最好的解决方案,但是每个线程或过程都需要支付一定的代价,而在Windows系统上,过程更加昂贵。至于调度程序,我不确定,但您可以设置进程和线程的优先级。线程的真正益处是它们的共享地址空间和无需IPC的通信能力,但是必须小心保持同步。

如果你的系统已经开发出来了,它似乎更容易实现一个多进程解决方案,特别是如果有可能使用后者多于一台机器。由于一台机器上的2个进程的IPC可在一般情况下扩展到多台机器。大部分并行化尝试都失败了,因为整个系统没有对瓶颈进行评估。例如,如果你实现了100个线程,所有的线程都写入同一个数据库,那么在实际性能上可能会获得很少的收益,只需等待数据库即可。

只是我的.02

+1

是的,我们已经面对它。数据库是主要的瓶颈。不要冒犯任何人,但是与sql服务器相比,我们的oracle性能要好得多。但在我们这个地区,我们大部分的客户都坚持使用sql server(价格便宜),这对我们来说是一个瓶颈。 – 2010-10-15 07:53:52

3

您无法处理比CPU核心更多的请求。 “快速”可扩展解决方案涉及设置线程池,其中活动(未在IO上阻塞)线程数量== CPU内核数量。所以创建100个线程,因为你想要服务100 msmq请求是不好的设计。

Windows有一个线程池机制,称为IO Completion Ports。因为在多进程设计中,每个进程都有自己独立管理的IO完成端口线程池,因此您可以获得更多的线程争用用于CPU内核。

IO完成端口的“核心”思想是它的内核模式队列 - 您可以手动将事件发布到队列中,或者通过将文件(文件,套接字,管道)关联到文件系统来自动发布异步IO完成与端口一起处理。另一方面,IO完成端口机制会自动将事件等待到等待的工作线程上 - 但是如果它检测到线程池中当前“活动”线程> = CPU核心数量,它不会使作业退出队列。

使用IO完成端口可能潜在地增加服务的可扩展性,但通常情况下,增益远小于预期,因为当所有CPU核心争用服务其他资源时,其他因素会迅速发挥作用。

如果你的服务是用C++开发的,你可能会发现对堆的序列化访问是一个很大的性能减去 - 虽然Windows版本6.1似乎已经实现了低争用堆,所以这可能不是一个问题。

总结 - 理论上你最大的性能提升是使用在一个单一的过程管理线程池的设计。但是,你严重依赖于你正在使用的库,不能序列化对关键资源的访问,这些资源很快就会失去理论上的性能收益。 如果你有库代码序列化的很好threadpooled服务(如对象创建&破坏C++的情况下被序列化,因为堆争用的),那么你需要你的图书馆/开关的使用来改变图书馆的低争版本或者只是扩展到多个进程。

要知道的唯一方法是编写测试用例,以各种方式强调服务器并测量结果。

+0

我一定会写测试用例。但我想知道如何在windows窗体理论上完成cpu调度。这可以帮助我分析测试 – 2010-10-15 07:50:55

+0

只是添加一个点,我们正在使用VS2008,我猜测它使用6.1 sdk。我怎么能证实这一点? – 2010-10-15 07:57:24

+0

您开发的SDK的版本并不重要 - 升级服务器后,“Windows 7”堆(Windows版本6.1)的性能提升会自动进行。 – 2010-10-15 08:24:45