如果要完成一千万次1+1+1+1的运算,要编写一个java程序运行,使用多少个线程去计算会最快完成?
在看《java并发编程实践》的时候有提到,如果一个处理不设计到io操作以及共享数据访问,那么分配当前cpu核心数目的线程去执行(或者+1)可以达到最快速度计算完成。
可以使用:Runtime.getRuntime().availableProcessors() 获取当前提供给java的可用核心数是多少。
这个时候有一个疑问,那么cpu的超线程技术和流水线技术没有影响吗???
流水线技术
流水线技术可以使得在同一时间之内执行多个指令。用5级流水线来说,同一时候cpu可以处理5条指令。
那么这个不是应该分配线程数为:5× 核心数 才对吗?
其实一个物理核心真正意义上在同一时间运行的只有一个线程。如果你在一个核心的情况下,你开启一个线程去计算。那么流水线技术会对你程序的指令组使用流水线进行处理。5级流水线能并行处理你程序的指令代码。但是如果你在程序中分配两个线程去执行计算,那么cpu执行线程A的时候,会去处理线程B的资源申请。这样线程A和线程B就会在cpu上发生竞争。这是最简单的情况,可能还有有共享内存资源的竞争。那么cpu去处理这些竞争就会消耗一定的处理资源。
即使线程之间不会发生竞争,但是流水线同时能处理的,也只有5个指令,和单线程时并没有任何优势可言。
不过不排除单线程执行时,由于处理指令之间的依赖关系而导致流水线阻塞不是本文所探讨的问题。
超线程技术的影响呢?
超线程是在一个物理核心中,有两个逻辑核心来提供双线程处理。在宏观上可以看做是重复利用cpu的闲置资源,双线程并行执行。但是如果双线程出现资源竞争的时候,反而会得不偿失,使得程序运行更加缓慢。所以说理论上可以由于超线程的存在,可以分配 核心数* 2 个线程数执行会最快。
在实际中,程序的执行逻辑也会起很大的作用,并不是这里提到的1+1运算这里简单的情况。
还有很多不大清楚的地方,待日后认识加深后更新。