【问题标题】:OS: Multiple Threads Slowing Down Program (C)操作系统:多线程减慢程序 (C)
【发布时间】:2014-06-09 03:40:42
【问题描述】:

这个想法是编写一个程序,该程序接受许多随机数来创建,然后在用户输入的线程数之间分配负载,并测量使用多个线程时我们获得的速度提升。我的问题;但是,我添加的线程越多,我的程序运行速度就越慢。不知道出了什么问题。到目前为止,这是我的代码的 sn-p:

...
    for (i=0; i<numThreads; i++){
        vals *values;
        values = (vals *)malloc(sizeof(vals));
        values->randoms = count;
        values->id = i;
        pthread_create(&tid[i], NULL, run, (void *) values);
    }

    for (i=0; i<numThreads; i++)
        pthread_join(tid[i], NULL);

    timeElapsed = getMilliSeconds() - timeStart;
    printf("Elapsed time:  %lf seconds\n",(double)(timeElapsed/1000.0));

    exit(EXIT_SUCCESS);
}

void *run(void *arg) {
    vals *values;
    long long int i;
    long long int randoms;

    values = (vals*)arg;
    randoms = values->randoms;
    srandom(values->id);

    for (i = 0; i < randoms; i++) {
        random();
    }

    pthread_exit(NULL);
}

vals 是一个包含两个 int 值(随机数和 id)的结构。 randoms 包含要生成的随机数数量除以线程数(以划分负载),并且 id 为每个用作种子的线程保存一个唯一的 id。我需要创建结构,以便将多个值传递给线程调用的工作函数。

任何想法为什么它会随着更多线程运行更慢?

【问题讨论】:

  • 你的机器有多少个内核?
  • 对不起,忘了提到核心数。目前我正在运行 2 个内核。
  • 您要完成多少工作?如果randoms 是一个相当小的数字,那么设置线程所花费的时间可能会大于完成工作所花费的时间。
  • 如果random() 必须锁定一个全局上下文来计算下一个随机值,这将很快发生。您可能需要查阅man-page,其中明确指出“在多个线程使用 random() 并且行为应该可重现的情况下不应使用此函数。为此目的使用 random_r(3)。”而且我认为在每个 thread 上调用 srandom() 也不是什么好主意。
  • 在worker函数中使用srandom和random不是我的主意,是项目需要的

标签: c multithreading


【解决方案1】:

在有多个 CPU 可用的环境中,多线程程序可能会显示出改进的性能。但是,当缺少可用的 CPU 资源时,每个线程都必须等待调度 CPU 时间。 “上下文切换”是指一个线程从 CPU 中切换出来,而另一个线程切换进来。“上下文切换”并不是一项无关紧要的任务。

因此,线程越多,等待 CPU 资源的线程就越多,内核用于上下文切换(而不是实际工作)的时间也就越多。

【讨论】:

    【解决方案2】:

    您很可能遇到false sharing。生成随机数涉及改变某些共享状态,并且多个线程不断修改相同的值有效地消除了您从 CPU 内存缓存中获得的任何好处。发生的情况是,每次线程 A 想要访问该共享状态时,它都必须等待线程 B 的 CPU 内核刷新其缓存。并且任何时候线程 B 想要访问它,它都必须等待线程 A 的 CPU 核心刷新它的缓存。

    换个角度看,单线程程序会执行以下操作:

    Load state into CPU cache
    for (i = 0 to randoms ...)
        generate random number
    

    有两个线程,每个线程都在这样做:

    for (i = 0 to randoms ...)
        wait for other CPU core to flush its cache
        generate random number
    

    我的问题;但是,我添加的线程越多,我的程序运行速度就越慢。

    如果您的处理线程数多于 CPU 内核数,那么您的程序将会变慢。使用两个内核,计算绑定操作的绝对最佳性能是运行速度是单线程解决方案的两倍。如果您有三个线程,那么在某些时候线程调度程序将不得不停止其中一个线程,以便第三个线程可以获得一些时间。这些上下文切换需要时间——在计算绑定操作的上下文中相对大量的时间。通常,您不希望拥有比 CPU 内核更多的计算密集型线程。

    (当然,没有超线程。使用超线程,您可能可能有四个线程同时运行,尽管您不太可能获得 3 倍的改进。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      • 2011-05-24
      • 2020-02-20
      • 2011-09-15
      • 1970-01-01
      相关资源
      最近更新 更多