Azul Systems推出了一种支持数千个高速缓存一致性处理器的设备。我希望能够了解,为了安排数千个同时运行的线程,操作系统需要进行哪些更改。
Azul Systems推出了一种支持数千个高速缓存一致性处理器的设备。我希望能够了解,为了安排数千个同时运行的线程,操作系统需要进行哪些更改。
调度数千个线程并不是什么大问题,但在数百个CPU上进行调度就比较棘手。首要需要的是非常细粒度的锁定,或者更好的是无锁数据结构和算法。您不能承受让200个CPU等待一个CPU执行关键部分。
您正在寻求对操作系统进行可能的更改,因此我假设有一个庞大的工程团队在这个努力背后。
还有一些澄清信息可以帮助定义问题参数:
您需要多少IPC(进程间通信)?
它们真的必须是线程吗,还是可以是进程?
如果它们是进程,那么它们是否可以通过套接字而不是使用共享内存来互相通信?
内存架构是什么样的?您是直接SMP,有1024个核心,还是有其他NUMA(非统一内存架构)或MMP?您的页表是什么样子的?
仅了解Azul系统的最基本信息,我猜测您几乎没有IPC,简单的“每个核心运行一个内核”的模型实际上可能会很好地工作。如果进程需要互相通信,那么它们可以创建套接字并以这种方式传输数据。您的硬件支持这种模型吗?(您可能最终需要每个核心一个IP地址,而且在1024个IP地址时可能会有问题,尽管它们都可以进行NAT,也许这不是一个大问题)。当然,这种模型会导致一些效率低下,例如额外的页表和相当多的RAM开销,甚至可能不受硬件系统支持。
即使“每个核心1个内核”不起作用,您也可以运行1024/8个内核,并且非常好,让每个内核控制8个物理CPU。
话虽如此,如果您想在具有1024个核心(仅有少数物理CPU)的传统SMP机器上每个核心运行1个线程,那么我希望您使用老式的O(1)调度程序。很可能您的CPU [0]最终将近乎100%地处于内核状态并处理中断,但对于这种用例来说,除非您需要超过1个核心来处理工作负载,否则这没问题。
我猜测每个处理器都有一个运行队列,并且在处理器空闲时会使用工作窃取算法。我可以看到这种模式在M:N模型中起作用,其中每个CPU都有一个单一的进程和轻量级进程作为工作项。然后,这将感觉类似于Java-7的fork-join库中的工作窃取线程池。
如果你真的想知道,可以阅读Solaris Internals或深入研究Solaris内核代码。我仍在阅读FreeBSD的Design & Impl,而Solaris Internals是我接下来要阅读的书籍,所以现在我只能做出猜测。
我非常确定我们工作中使用的SGI Altix(它支持ccNUMA)使用了用于高速缓存一致性的特殊硬件。
每个核心保持4mb高速缓存一致性会有巨大的开销。仅靠软件实现是不可能的。
在一个256个CPU的阵列中,您需要768mb内存来保存高速缓存失效位。 12mb高速缓存/每128字节高速缓存行 * 256²个核心。
最简单的方法是将每个进程/线程绑定到几个CPU,然后只有这些CPU需要竞争该线程的锁。显然,需要有一些方法来移动线程以平衡负载,但在NUMA架构上,必须尽可能地将其最小化。