java - 我可以相信操作系统调度线程 "optimal"(并行化)

标签 java multithreading operating-system

Afaik:适合并行处理的数据的最佳线程数是核心数 - 因为每个线程(理论上)都有一个自己的核心来运行。对于支持超线程的 CPU,它是核心数量的 2 倍。如果我错了请纠正我。

我的问题是底层操作系统(Linux、Winodws OSX)是否会自动实现我的“意图”,例如将每个线程分配给一个核心,假设我有例如8 个核心和相应的 8 个线程,其中每个线程都执行“耗时”任务?

或者反过来:是否可以将线程分配给内核(尤其是在 Java 中)?

最佳答案

Afaik: The optimal number of threads for data that is suitable for parallel processing is the number of cores - since each thread has (theoretically) a core of its own to run on. For CPUs that are capable of hyper-threading it is 2x the number of cores. Please Correct me if I am wrong.

事情远比这复杂得多。

这取决于您要优化的目标。如果您正在优化以有效(即具有成本效益)地使用可用硬件,那么它很少是最佳的。如果任何线程由于任何原因需要等待很长一段时间,那么将线程一对一分配给物理核心会导致核心利用率不足。如果这些核心可以用于其他用途(例如运行其他人的程序!),那么您的使用不是最佳的。

即使您仅针对应用程序速度进行优化,一对一分配也不一定是最佳策略。

  • 每个应用程序+工作负载在线程数量方面都有一个“最佳点”。这取决于任何内部争用的数量和性质,以及与外部系统(文件系统、网络等)通信的数量和性质。

  • 如果您有严格的每核一个线程规则,那么您在 N 核系统上最多可以有 N 个线程。

  • 如果 N 明显小于线程的“最佳点”数量,您可能会发现核心在很多时候处于空闲状态。

现在是超线程。

超线程可能会在每个时钟周期为您提供额外的 CPU 周期。但是,它们不会在内存系统中提供额外的周期。超线程“虚拟核心”的性能特征将不同于物理核心……对于现实应用程序来说,差异将是显着的。因此你的 2 x 假设是没有根据的。

My question is if the underlying OS (Linux, Winodws OSX) will automatically realize my "intention" and e.g. assigns each thread to a single core assuming I have e.g. 8 cores and accordingly 8 threads where each of them works on a "time consuming" task?

不一定。

  • 操作系统必须考虑系统上发生的其他事情。其他应用程序、处理桌面的守护进程等、处理文件系统和网络协议(protocol)的东西。

  • 操作系统(和 JVM)通常只会对做出调度决策时已经发生的情况使用react。根据过去的行为(在这个级别)预测 future 的行为并不具有成本效益……并且现代操作系统不会尝试这样做,除非在非常粗略/启发式的水平上。完美(最优)预测是不可能的,即使你有完美的知识,调度问题也是 NP 困难的。

理论上,应用程序程序员可以设计最佳的时间表。实际上,大多数应用程序都过于复杂,而且很难考虑系统上发生的其他“随机”事情。

Or the other way around: Is it possible to assign threads to cores (especially in Java)?

没有实际的方法可以做到这一点。 (参见@ksmonkey123的回答)当然,不可移植。

而且它可能不太可能在 Java 中工作。 Java 还有一个额外的问题,即存在隐藏的线程在应用程序背后执行操作(例如垃圾收集器和终结器线程),并且 Java 内存管理更难以预测且更难以调整。

关于java - 我可以相信操作系统调度线程 "optimal"(并行化),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27061762/

相关文章:

java - 使用 assertArrayEquals 使用 JUnit 进行测试时出错

Java javax 计时器问题?

java - Java中的StoreStore内存屏障是否禁止读写重新排序?

java - 如何在 JNI 环境的 native 端正确同步线程?

java - 如何在 Java 中正确使用 "throws clause"?

android - GUI 不显示所有收到的数据包

java - 这段代码线程安全吗?静态方法修改httpservletrequest

java - 如何找到处理器的负载能力?

c - 在物理内存中动态创建数组

macos - 在 MacOS 中仅删除一个用户的 ACL 条目?出奇地困难