我有8个任务要在octo-core机器上运行。所有任务都是CPU密集型的,每个任务都会最大化核心。
是否有理论上的理由避免在最大化核心上堆叠任务(例如开销,跨任务交换)或排队所有内容的速度更快?
答案 0 :(得分:1)
任务切换浪费了CPU时间。如果可以,请避免使用它。
无论调度程序的时间片设置如何,CPU都会通过进入内核,保存所有寄存器,交换内存映射以及启动下一个任务来节省每个时间片的时间。然后它必须加载所有的CPU缓存等。
一次只运行一项任务会更有效率。
如果任务使用I / O并且不是纯粹计算绑定,那么事情就不同了。
答案 1 :(得分:0)
是的,它被称为排队论https://en.wikipedia.org/wiki/Queueing_theory。对于一系列不同的问题有许多不同的模型https://en.wikipedia.org/wiki/Category:Queueing_theory我建议您扫描它们并选择最适合您的工作负载的模型然后去阅读如何避免该模型的最坏结果,或者选择一种不同的,更好的模型,用于调度您的工作量。
虽然此链接https://commons.wikimedia.org/wiki/File:StochasticQueueingQueueLength.png上的图表适用于流量,但它会让您了解CPU利用率增加时响应时间发生了什么。它表明你会达到拐点,之后事情变得越来越慢。
到达的工作量超过了后续工作等待时间越来越长的工作,直到可以发送为止。
你越往右边的核心就越多,你就会推动拐点,但是当你到达拐点后,事情会变得更快。
我还要注意,除非你有一些非常严重的冷却,否则你将会煮你的CPU。根据它的设计,它会使自身减速,使问题变得更糟,或者你会触发它的热过载保护。
因此,8个内核的简单设计是,1个线程来管理事物并将任务添加到工作队列,7个线程从工作队列中提取任务。如果需要在一定时间内执行任务,则可以添加TimeToLive值,以便可以丢弃它们而不是不必要地执行它们。由于您几乎可以肯定在使用抢占式线程模型的操作系统中运行应用程序,因此请考虑使用处理器关联性,因为@ Zan-Lynx表示任务/上下文切换会受到伤害。小心不要再次尝试建立你的OS'es线程管理,因为你可能最终会与它发生冲突。
答案 2 :(得分:0)
你有十几个任务。每个人都必须做一定的工作。
在应用级别,他们每人处理了一千条客户记录或其他任何内容。这是固定的,无论硬件上发生什么,它都是一个常量。
在语言级别,它再次被修复,C ++,java或python将执行固定数量的应用程序指令或字节码。我们将在这里掩饰gc开销,以及页面错误和调度细节。
在程序集级别,它再次被修复,当应用程序继续发出新指令时,会执行一些x86指令。
但是你不关心多少指令,你只关心执行这些指令需要多长时间。许多指令是MOV从RAM到寄存器的值的读取。想想需要多长时间。您的计算机有几个组件来实现内存层次结构 - 哪些将涉及?这个读取会在L1缓存中命中吗?在L2?它是否会在最后一级缓存中丢失,因此您等待(数十或数百周期),直到RAM提供该缓存行?虚拟内存引用是否在RAM中丢失,因此您等待(毫秒),直到SSD或Winchester存储可以在所需的帧中进行寻呼?您认为您的应用程序是发布N次读取,但您可能会更有效地将其视为发出0.2 * N缓存未命中。在不同的多编程级别运行,发出0.3 * N缓存未命中,可能会使经过的时间明显变长。
每个工作负载都不同,可能会对内存存储提出更大或更小的要求。但是内存层次结构的每个级别都在某种程度上依赖于缓存,并且更高的多编程级别可以保证影响缓存命中率。存在网络和I / O繁重的工作负载,其中非常高的多编程级别绝对有意义。但对于CPU和内存密集型工作负载,当您对经过时间进行基准测试时,您可能会发现更少。