【问题标题】:Compile a C program with GCC, so that it can use all cpu cores in linux用 GCC 编译一个 C 程序,使其可以使用 linux 中的所有 cpu 内核
【发布时间】:2017-11-28 09:28:34
【问题描述】:

我有一个用于添加的示例 C 程序。当我使用 GCC 编译和运行它时,它只使用一个 CPU 内核。

有没有办法编译一个C程序,让它可以使用Linux中的所有CPU内核。

我以前编译喜欢gcc -O3 malloc.c

代码:

#include <stdio.h>
#include <time.h>
#include <malloc.h>

int main() {
        float *ptr;
        unsigned long long i;

        ptr = (float*) malloc(8000000000 * sizeof(float));

        for(i=0; i<8000000000; i++) {
                ptr[i] = i/10000;
        }

        clock_t tic = clock();

        for(i=0; i<8000000000; i++) {
                ptr[i] = (i/10000)+1.0;
        }

        clock_t toc = clock();

        printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);

        return 0;
}

【问题讨论】:

  • 如果你使用 make buildtool 那么你可以使用 -j 标志,你可以同时工作。对于 4 个核心,您可以像 make -j4 这样给出,这是您的要求吗?
  • &lt;malloc.h&gt; 是非标准的,可能已被弃用。使用&lt;stdlib.h&gt;
  • @LethalProgrammer: make -j 在构建时相关,而不是在运行时
  • @BasileStarynkevitch,我不确定 OP 要求什么,这就是为什么我只是提出这个问题来澄清。如果他想在运行时执行此操作,那么我同意您使用 make 毫无意义。
  • 我的适应就像拨动开关一样简单,为什么不默认开启?

标签: c linux gcc


【解决方案1】:

有没有办法编译一个C程序,让它可以使用Linux中的所有CPU内核。

,没有你想要的那么神奇。 Parallelization 的程序是一个非常困难的主题,通常不能自动完成。顺便说一句,并行程序可能没有您希望的那么高效(注意Amdahl's law)。

但是,您可以设计编码一个并行程序。例如,您可以使用posix threads。当心,这很棘手!先阅读一些Pthread tutorial。您不确定是否会使用所有cores(因为它们由kernel 管理),但实际上很有可能。另请阅读processor affinity

您也可以使用OpenMPOpenACC。您可以使用OpenCL 对一些数字内核进行编码。您可以使用multi-processing 方法(例如,分叉多个processes,使用inter-process communications),也许使用MPI。还可以查看MapReduce 方法、0mq 库(以及许多其他方法)。

您可以在操作系统上阅读一些内容,例如Operating Systems: Three Easy Pieces。您还可以阅读有关 Linux 系统编程的内容,例如Advanced Linux Programming(或一些较新的书)。另请参阅 intro(2)syscalls(2)pthreads(7)

请注意,设计、编码和调试parallel(或并发,或distributed应用程序非常困难。考虑开发时间的成本(以及获得相关技能所需的时间,可能是years)。有No Silver Bullet

(将现有的现实生活中的顺序应用程序转换为并行应用程序不太现实;您通常必须从头开始设计并行程序)

【讨论】:

  • -ftree-parallelize-loops=4 还在 gcc 中工作吗?如果是这样,它可能会在这种简单的情况下工作,因为循环的编译时间常数很大。
  • 可能是的,但你应该尝试(答案可能是特定于编译器版本)
【解决方案2】:

尝试在 for 循环上方添加以下编译指示:

#pragma omp parallel for
for(i=0; i<8000000000; i++) {
    ptr[i] = i/10000;
}

并在调用 gcc 时将 -fopenmp 选项添加到您的构建选项中。默认情况下,OpenMP 将在您的机器中创建与内核一样多的线程,并在它们之间平均分担工作量。

您可以查看此article 了解有关 OpenMP 的更多信息。

【讨论】:

  • 好!这将第二个 for 循环的时间从 8.48 秒更改为 1.48 秒。这快了 5.7 倍,这正是我的 6 核 i7 cpu 所期望的。
【解决方案3】:

您需要创建多个线程。否则只有一个线程,并且(一次)在一个内核上运行。

查看有关线程的教程,特别是 pthreads,了解如何使用线程。或者您可以使用 fork 系统调用将您的程序拆分为多个进程,每个进程都有一个线程。

【讨论】:

  • 可能是多进程程序,而不是多线程程序
  • @BasileStarynkevitch:是的。
  • 创建多个线程或进程(相对)容易。难的是如何划分工作,以便他们真正能够独立进行,但在需要时进行协调。
  • 我认为线程或进程之间的同步和通信并不容易。我的看法是很难
  • @BasileStarynkevitch:我想每个人都同意你的观点。我认为 Triplee 的意思是调用 pthread_create 很容易。其余的都是困难的。
【解决方案4】:

您可以在程序中创建n(n 是假定的核心数)线程,然后您可以设置每个线程的CPU 亲和性,以便它与特定的CPU Core 绑定。 sched_setaffinitypthread_setaffinity_np 是允许您设置CPU 亲和力的选项。

【讨论】:

    猜你喜欢
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    相关资源
    最近更新 更多