我正在使用 Java 的具有 32 个虚拟处理器的服务器上进行网络爬取。我怎样才能充分利用这些处理器?我已经看到了一些关于多线程编程的建议,但我想知道如何确保所有处理器都被利用,因为我们也可以在单处理器机器上进行多线程编程。
3 回答
对此没有简单的答案......除了确保使用所有处理器的方法是正确使用多线程。(注意:这是一个循环答案!)
基本上,有效使用多个处理器的方法是:
- 确保有可以并行完成的工作,并且
- 减少/消除强制一个线程等待而另一个线程做某事的争用点。
当您进行简单计算时,这已经足够困难了。对于网络爬虫,您会遇到线程竞争网络和(可能)删除服务器带宽的额外问题,并且它们通常会尝试将其结果放入共享数据结构或数据库中。
这就是在这个一般性级别上可以说的所有内容......
正如@veer 正确指出的那样,您不能“确保”它。
...但是使用大量线程肯定会在墙上时间上更快,因为所有可悲的网络延迟都将并行发生...
实际上,如果过度使用,线程负载会因为争用而降低吞吐量。仅仅在问题上投入大量线程并不是一个好主意。
处理器管理是通过您使用的虚拟机(即 JVM)以本机方式实现的。如果您使用 Java Hotspot VM,您可以在这里查看Java Hotspot VM Options来优化您的机器。如果您使用的是第三方 VM,那么您的提供商可能会帮助您根据您的要求对其进行调整。
设计中的应用性能实际上取决于您。如果您想监控线程和内存使用情况以优化您的应用程序,您可以使用迄今为止可用的任何 VM 监控工具。Java 虚拟机 (JVM) 具有内置工具,使您能够使用 JMX 监视和管理它。有关详细信息,您可以使用 JMX 检查平台监控和管理。对于第三方虚拟机,我猜你必须联系供应商。
计算机或程序的速度取决于其处理链中最慢的环节。仅仅增加 CPU 容量并不能确保性能达到峰值。撇开缓存大小、RAM 等其他问题不谈,关于如何利用所有处理器的问题,有两种基本方法:
[1] 使用 Jit/just-in-time 编译器/解释器技术,例如 Java/.NET。我对 java 了解不多,但 .NET 抖动绝对是为了利用机器上所有可用的处理器而设计的。事实上,这个特性使得 jitter 在其他静态语言编译器(如 C/C++)中脱颖而出,因为 jitter “知道”它位于 32 个处理器上,它比程序更能利用它们在任何其他机器上静态编译。(前提是你已经为它写了一个健壮的多线程代码!)
[2] C/C++ 编程。这是经典的方法。如果您在具有 32 个 CPU 的同一台机器上编译您的代码,并在您的程序中采取适当的措施,例如内存管理、处理指针等,那么 C/C++ 程序将是最佳的,并且会比其 CLR/JVM 执行得更好对应物(因为它在没有垃圾收集器或 VM 的额外开销的情况下运行)。
但请记住,在 .NET/Java 中编写健壮的代码比在 C/C++ 中容易得多。因此,如果您不是“铁杆”程序员,我建议您采用前一种方法。还要记住要小心处理多个线程,例如当多个线程尝试更改相同的变量时锁定变量。但是,如果变量出现意外行为,过度锁定可能会使您的代码挂起。