我试图找出如何从多线程应用程序中获得最大性能.
我有一个我创建的线程池,如下所示:
ExecutorService executor = Executors.newFixedThreadPool(8); // I have 8 CPU cores.
我的问题是,我应该将工作分成只有8个runnables/callables,这与线程池中的线程数相同,还是应该将它分成1000000 runnables/callables呢?
for (int i = 0; i < 1000000; i++) { Callableworker = new MyCallable(); // Each worker does little work. Future submit = executor.submit(worker); } long sum = 0; for (Future future : list) sum += future.get(); // Much more overhead from the for loops
要么
for (int i = 0; i < 8; i++) { Callableworker = new MyCallable(); // Each worker does much more work. Future submit = executor.submit(worker); } long sum = 0; for (Future future : list) sum += future.get(); // Negligible overhead from the for loops
分为1000000个callable对我来说似乎比较慢,因为实例化所有这些callables并从for循环中收集它们的结果.另一方面,如果我有8个callables,这个开销可以忽略不计.由于我只有8个线程,因此我不能同时运行1000000个callables,因此没有性能提升.
我是对还是错?
顺便说一句,我可以测试这些情况,但操作非常简单,我想编译器意识到并进行了一些优化.所以结果可能会产生误导.我想知道哪种方法更适合像图像处理应用程序.
这个问题没有直接的答案,因为它取决于你的代码,应用程序loigc,max,可能的并发,hw等很多东西.
但是在考虑并发时你应该考虑下面的事情,
每个runnable都需要一个专用于该线程的堆栈,因此如果你创建了大的no.线程中的线程内存消耗大于实际应用程序的使用
线程应该执行独立且并行的任务.
找出可以实际并行执行的代码补丁,没有任何依赖,否则线程无济于事
什么是硬件配置?
您可以实现的线程的最大并发执行数等于总数.的cpu核心.如果你少了没有.核心和巨大的没有.然后切换任务比实际线程更活跃(使用cpu).这可能会严重影响性能
总而言之,你的第二种方法看起来对我很好,但如果可能的话,找出更多的并行性,你可以将它扩展到20-30.