6

我在具有 24 个内核的共享 Linux 计算机上运行大规模并行科学计算作业。大多数时候,当这台计算机上没有运行其他任何东西时,我的工作能够扩展到 24 个内核。但是,似乎即使不是我的一个单线程作业也在运行,我的 24 线程作业(我将其设置为高值)只能设法获得 ~1800% 的 CPU(使用 Linux 表示法)。同时,大约 500% 的 CPU 周期(同样,使用 Linux 表示法)是空闲的。谁能解释这种行为以及我能做些什么来获得其他人未使用的所有 23 个内核?

笔记:

  1. 万一它是相关的,我在稍微不同的内核版本上观察到了这一点,尽管我不记得是哪一个在我的脑海中。

  2. CPU架构是x64。我的 24 核工作是 32 位的,而我正在竞争的其他工作是 64 位这一事实有可能吗?

编辑:我刚刚注意到的一件事是,增加 30 个线程似乎在一定程度上缓解了这个问题。它使我的 CPU 达到 ~2100%。

4

5 回答 5

7

这可能是由于调度程序试图让你的每个任务都运行在它之前运行的同一个 CPU 上(它这样做是因为任务可能已将其工作集带入该 CPU 的缓存 - 它是“缓存热”)。

以下是您可以尝试的一些想法:

  • 运行两倍于核心的线程;
  • 运行的线程比核心少一到两个;
  • 减少/proc/sys/kernel/sched_migration_cost(可能降至零)的值;
  • 将 down的值减小到/proc/sys/kernel/sched_domain/.../imbalance_pct接近 100。
于 2010-05-14T01:53:00.413 回答
2

你的线程必须同步吗?如果是这样,您可能会遇到以下问题:

假设您有一个 4-cpu 系统和一个 4 线程作业。单独运行时,线程扇出以使用所有 4 个内核,总使用率接近完美(我们称之为 400%)。

如果您添加一个单线程干扰作业,调度程序可能会将您的 2 个线程放在同一个 cpu 上。这意味着您的 2 个线程现在以正常速度的一半有效运行(显着简化),如果您的线程需要定期同步,您的工作进度可能会受到最慢线程的限制,在这种情况下运行速度为正常速度的一半。您将看到只有 200% 的利用率(从您的作业运行 4x 50%)加上 100%(干扰作业)= 300%。

同样,如果您假设干扰作业仅使用一个处理器 25% 的时间,您可能会看到您的一个线程和干扰者在同一个 CPU 上。在这种情况下,最慢的线程以 3/4 正常速度运行,导致总利用率为 300% (4x 75%) + 25% = 325%。使用这些数字,不难想出与您所看到的类似的东西。

如果这是问题所在,您当然可以使用优先级,只为不受欢迎的任务提供一小部分可用 CPU(我假设 I/O 延迟不是一个因素)。或者,正如您所发现的,尝试增加线程,以便每个 CPU 有 2 个线程,减去一些线程以允许系统任务。以这种方式,24 核系统可能会以 46 个线程运行得最好(这总是使 2 核的一半时间可用于系统任务)。

于 2010-05-13T22:00:43.693 回答
1

您的线程是否相互通信?

尝试使用sched_setaffinityor手动将每个线程绑定到 cpu pthread_setaffinity_np。在处理大量相关线程时,调度程序可能相当愚蠢。

于 2010-05-16T04:28:32.337 回答
0

您认为瓶颈在于您的应用程序还是内核的调度算法?在您开始调整调度参数之前,我建议您尝试运行一个简单的多线程应用程序,看看它是否表现出与您的应用程序相同的行为。

// COMPILE WITH: gcc threads.c -lpthread -o thread
#include <pthread.h>
#define NUM_CORES 24

void* loop_forever(void* argument) {
    int a;
    while(1) a++;
}

void main() {
    int i;
    pthread_t threads[NUM_CORES];

    for (i = 0; i < NUM_CORES; i++)
        pthread_create(&threads[i], 0, loop_forever, 0);

    for (i = 0; i < NUM_CORES; i++)
        pthread_join(threads[i], 0);
}
于 2010-05-15T02:30:11.167 回答
0

可能值得使用mpstatsysstat包的一部分)来确定您是否有整个 CPU 处于空闲状态而其他 CPU 已被充分利用。它应该为您提供比 top 或 vmstat 更详细的利用率视图:运行mpstat -P ALL以查看每个 CPU 1 行。

作为一个实验,您可以尝试在每个线程上设置 CPU 亲和性,以便每个线程都绑定到一个单独的 CPU;如果您不让内核调度程序决定将任务安排在哪个 CPU 上,这将让您了解性能如何。这不是一个好的永久解决方案,但如果它有很大帮助,它可以让您了解调度程序的不足之处。

于 2010-05-13T18:27:42.933 回答