多核多线程能否避免缓存未命中
Can multi cores and multi threading avoid cache miss
我知道在单核机器上,多线程编程会增加缓存未命中,因为每个线程都有自己的堆栈和指令指针等。所以当多线程进行上下文切换时,CPU 必须重新加载另一段 RAM,这会给我们缓存未命中。
所以我在想多核是否可以避免这个问题?说我有一个包含两个线程的程序,我的机器有两个内核。如果每个线程都可以分配到不同的核心,这是否意味着我可以避免缓存未命中问题?
答案一如既往,视情况而定。
假设单独的内核带有单独的 L1 缓存(不能保证,但足够普遍),那么是的,缓存未命中的情况会更少。但这确实取决于每个线程正在处理多少数据"in one lump",以及在需要获取新数据之前对其进行了多少处理。如果这不仅仅是单独内核上的缓存,那么两者的缓存将被提升到(至少在 Intel CPUs 上)共享的 L3 缓存。 L3缓存然后成为瓶颈。如果数据甚至溢出,那么它会返回到 SDRAM,这非常慢。如果数据集大于系统的 RAM,那么这就是 OS 的页面文件的用途,而且速度非常慢。
CPU 设计人员通常打赌他们选择的缓存架构将满足广泛的 "typical" 应用程序,并且他们在这方面非常成功。但是,如果您真的非常想要最后 % 的性能,那么缓存引擎的 "cleverness" 可能会开始对程序员不利。缓存可能会猜测您的程序接下来要访问数据 X,但实际上它要求访问数据 Y。缓存未命中,速度大大降低。准确了解芯片上的缓存架构在任何特定情况下的作用可能非常困难,甚至在编写代码时也难以适应。
一些缓存允许程序员放置提示 - PowerPC 7400 系列可以做到这一点,而且非常有用。程序可以不依赖于缓存引擎猜测,而是可以明确地告诉缓存,如果可以的话,缓存开始加载数据 Y 是非常值得的。提前使用该指令,当程序实际获取时围绕处理它,它已经在缓存中。没有缓存未命中。如果程序员足够聪明,知道他们可以提供比缓存猜测更好的提示,则程序员只需要在程序的正确位置包含相关指令。
IBM 的 Cell 处理器(比如:Sony Playstation 3)将这一点发挥到了极致。根本没有缓存。相反,芯片上的每个数学核心都有 256k 的 RAM,具有单周期访问(因此,就像 L1 缓存一样)。完全由程序员将数据和代码从片外 RAM 加载到 RAM 中。它很难编程,但一旦掌握它就会非常非常快。
我知道在单核机器上,多线程编程会增加缓存未命中,因为每个线程都有自己的堆栈和指令指针等。所以当多线程进行上下文切换时,CPU 必须重新加载另一段 RAM,这会给我们缓存未命中。
所以我在想多核是否可以避免这个问题?说我有一个包含两个线程的程序,我的机器有两个内核。如果每个线程都可以分配到不同的核心,这是否意味着我可以避免缓存未命中问题?
答案一如既往,视情况而定。
假设单独的内核带有单独的 L1 缓存(不能保证,但足够普遍),那么是的,缓存未命中的情况会更少。但这确实取决于每个线程正在处理多少数据"in one lump",以及在需要获取新数据之前对其进行了多少处理。如果这不仅仅是单独内核上的缓存,那么两者的缓存将被提升到(至少在 Intel CPUs 上)共享的 L3 缓存。 L3缓存然后成为瓶颈。如果数据甚至溢出,那么它会返回到 SDRAM,这非常慢。如果数据集大于系统的 RAM,那么这就是 OS 的页面文件的用途,而且速度非常慢。
CPU 设计人员通常打赌他们选择的缓存架构将满足广泛的 "typical" 应用程序,并且他们在这方面非常成功。但是,如果您真的非常想要最后 % 的性能,那么缓存引擎的 "cleverness" 可能会开始对程序员不利。缓存可能会猜测您的程序接下来要访问数据 X,但实际上它要求访问数据 Y。缓存未命中,速度大大降低。准确了解芯片上的缓存架构在任何特定情况下的作用可能非常困难,甚至在编写代码时也难以适应。
一些缓存允许程序员放置提示 - PowerPC 7400 系列可以做到这一点,而且非常有用。程序可以不依赖于缓存引擎猜测,而是可以明确地告诉缓存,如果可以的话,缓存开始加载数据 Y 是非常值得的。提前使用该指令,当程序实际获取时围绕处理它,它已经在缓存中。没有缓存未命中。如果程序员足够聪明,知道他们可以提供比缓存猜测更好的提示,则程序员只需要在程序的正确位置包含相关指令。
IBM 的 Cell 处理器(比如:Sony Playstation 3)将这一点发挥到了极致。根本没有缓存。相反,芯片上的每个数学核心都有 256k 的 RAM,具有单周期访问(因此,就像 L1 缓存一样)。完全由程序员将数据和代码从片外 RAM 加载到 RAM 中。它很难编程,但一旦掌握它就会非常非常快。