java什么时候一个线程比多个线程并发运行快
对于一个任务,我必须实现一个Java程序,当使用多个线程运行时,实际上比仅使用1个线程运行时要慢。我知道创建线程需要一些开销,但在本例中,我处理的是一个大数组20000x2000。没有依赖关系,所以创建4个较小的块并同时运行它们的好处应该总是超过创建线程的成本,对吗
for (int i = 0; i < numThreads; i++) {
// for each iteration of the body's for loop,
// calculate the starting and ending indexes
// of the ith chunk of the y dimension of
// the anArray array
final int indexStart = i * chunkSize;
final int indexEnd = (i + 1) * chunkSize;
// each "execute" method of the Executor class
// creates a new object of type Runnable ...
// be careful with the parentheses here ... the
// entire next code block is being passes
// as a parameter to the execute method
ex.execute(new Runnable() {
// The run() method is declared abstract in the Runnable
// class, so it MUST be overriden. The body of the
// run method is the "code" that each thread executes
@Override
public void run() {
for (int j=0; j<anArray.length; j++){
for (int k = indexStart; k < indexEnd; k++){
anArray[j][k] = anArray[j][k] * anArray[j][k] / 3.45 * Math.sqrt(anArray[j][k]);
}
} // end for
} // end run
}
);
}
我们的任务是只修改最里面的for循环,我们可以在那里做任何我们想做的事情,但是当使用更多线程执行时,它必须使运行时变慢。上限为8个线程。 我真正的问题是,在实现多个线程时,什么会导致更多的问题。我做了一些研究,发现你可以用一个线程来使用大部分cpu,所以创建更多线程是没有帮助的,这怎么可能呢
# 1 楼答案
以下是一些:
如果您正在创建自己的线程:在每个线程上创建和启动N个线程并运行M个任务所需的时间大于在单个线程上运行N*M个任务所需的时间。提示:启动Java线程很昂贵
如果您正在使用
Executor
,则计划任务所需的时间很长,执行任务所需的时间很长当你有太多的线程相对于内核的数量。提示:多线程(用于计算绑定任务)所能获得的加速受内核数量的限制,而不是线程数量的限制
当任务存在固有的并发瓶颈时,例如访问/更新公共的同步数据结构
当任务涉及跨多个线程访问大量内存单元时,会出现大量内存缓存未命中和内存争用
当你在基准测试中犯了错误;e、 g.当你没有适当考虑“JVM预热”效应时
如果你有4个内核,那么在这个例子中运行100个线程不会给你比4个线程更多的加速。现在再加上这样一个事实:你有启动96个线程的开销,这对你没有帮助。。。这可以解释为什么多(100)个线程比单个线程慢
此外,您的示例可能会生成大量缓存未命中和内存流量。看起来你将读取和写入一个包含4亿个元素的数组中的每个单元。内存争用将成为瓶颈
# 2 楼答案
多线程独立运行时效果最好。这意味着任何对共享资源的过度利用都会限制甚至降低多线程的使用速度
假设你有一个4芯的插座。这意味着您有4个内核,每个内核有32 KB的一级缓存。如果你使用的内存超过这个数量,他们必须使用二级缓存,这大约是3-4倍的速度。但这些内存只有256KB。如果你使用的不止这些,他们必须使用唯一的三级缓存。i、 e.使用超过1MB的内存,你的应用程序将无法扩展,速度可能会变慢
在您的例子中,您还使用浮点单位esp Math。sqrt占用了相当多的CPU。每个内核只有一个FPU,所以你可能会发现使用超线程并没有多大帮助。(或许<;10%)
简而言之,考虑到浮点操作非常昂贵,我希望您能够获得良好的可扩展性,最多可扩展到现有的内核数。随着内核的增加,在某个时候,L3缓存将成为瓶颈。e、 g.对于18核,你可能会发现这是一个问题