【问题标题】:thread overhead performance线程开销性能
【发布时间】:2013-02-09 11:11:25
【问题描述】:

在使用 C 语言编程时,在 Linux shell 中,我试图减少线程开销,基本上是降低 CPU 时间(并提高效率)。

现在在程序中创建了许多线程,需要在它终止之前完成一项工作。由于互斥,只有一个线程可以同时完成工作。

我知道一个线程在开始之前完成一项工作需要多长时间

当有线程执行该工作时,其他线程必须等待。他们检查是否可以完成工作的方式是是否满足条件变量。

对于等待线程,如果他们使用那个条件变量等待,使用这个特定的代码等待(a、b、c 和 d 只是任意的东西,这只是一个例子):

while (a == b || c != d){
    pthread_cond_wait(&open, &mylock);
}

这效率如何? pthread_cond_wait 代码中发生了什么?是一个不断检查条件变量的while循环(在幕后)吗?

另外,既然我知道一个线程将花费多长时间,那么我首先执行关于最短作业的调度策略是否更有效?或者这无关紧要,因为在执行这项工作的任何线程组合中,程序将花费相同的时间来完成。换句话说,是否首先使用最短作业会降低其他线程等待的 CPU 开销?因为最短的工作首先似乎可以缩短等待时间。

【问题讨论】:

  • 您能否重写您的问题以使其更清楚?另外,您想知道不使用互斥锁而只是手动安排内容吗?
  • 您需要阅读操作系统教科书。 Condvars 和其他同步机制不是 while() 循环,高效的多线程设计非常努力地避免同步,或者,如果不可避免,最小化它的跨度。您正在尝试运行 b4 walk。
  • 好的,我试图让它更清楚(我编辑了上面的问题)。所以基本上我要问的是,如果我使用调度策略首先做最短的工作,那么这应该最大限度地减少没有完成工作的线程的等待时间。正因为如此,这是否意味着总的等待时间减少了,从而减少了整体 cpu 时间?由于任何形式的等待仍然会占用一些 CPU 时间,对吧?
  • 注意我的编辑以详细回答这个问题。

标签: c linux multithreading synchronization mutex


【解决方案1】:

使用单个线程解决您的问题,如果您还看不到需要最少锁定的途径,请向我们寻求帮助,以确定公开并行化的最佳位置。要使用的最佳线程数取决于您使用的计算机。使用超过 n+1 个线程没有多大意义,其中 n 是程序可用的处理器/内核数。为了减少线程创建开销,最好为每个线程分配多个作业。

以下是对您的澄清编辑的回应:

现在在程序中创建了很多线程,需要做一个 在它终止之前的工作。只有一个线程可以同时完成这项工作 时间因为互斥。

没有。如上所述,最多应创建 n+1 个线程。你说的互斥是什么意思?我认为互斥是“只有一个线程在其工作队列中包含任务 x”。这意味着没有其他线程需要锁定任务 x。

当有线程执行该工作时,其他线程必须等待。这 他们检查是否可以完成工作的方式是条件变量是否为 遇到了。

给每个线程一个独立的任务列表来完成。如果作业 x 是作业 y 的先决条件,那么作业 x 和作业 y 理想情况下应该在同一个列表中,这样线程就不必处理任一作业上的线程互斥对象。你探索过这条路吗?

而 (a == b || c != d){ pthread_cond_wait(&open, &mylock); } 这效率如何? pthread_cond_wait 代码中发生了什么? 是否是一个不断检查 条件变量?

为了避免未定义的行为,mylock必须在调用pthread_cond_wait之前被当前线程锁定,所以我假设你的代码在进入这个循环之前调用pthread_mutex_lock来获取mylock锁。

  1. pthread_mutex_lock 阻塞线程直到它获得锁,这意味着一次有一个线程可以执行 pthread_mutex_lock 和 pthread_cond_wait 之间的代码(pre-pthread_cond_wait 代码)。
  2. pthread_cond_wait 释放锁,允许其他线程运行 pthread_mutex_lock 和 pthread_cond_wait 之间的代码。在 pthread_cond_wait 返回之前,它会一直等待,直到它可以再次获取锁。此步骤重复 adhoc while (a == b || c != d)
  3. pthread_mutex_unlock 稍后在任务完成时调用。在此之前,一次只有一个线程可以执行 pthread_cond_wait 和 pthread_mutex_unlock 之间的代码(pthread_cond_wait 后代码)。此外,如果一个线程正在运行 pre-pthread_cond_wait 代码,则没有其他线程可以运行 post-pthread_cond_wait 代码,反之亦然。

因此,您不妨运行将作业存储在优先级队列中的单线程代码。至少你不会有不必要的和过多的上下文切换。正如我之前所说,“用一个线程解决你的问题”。在您有衡量标准之前,您无法就优化节省了多少时间做出有意义的陈述。

另外,既然我知道一个线程需要多长时间,是不是更 有效地执行有关最短作业的调度策略 第一的?或者这无关紧要,因为在任何线程组合中 做这项工作,程序将花费相同的时间 结束。换句话说,是否使用最短作业首先降低 CPU 其他线程等待的开销?由于最短的工作 首先似乎减少了等待时间。

如果您要执行调度策略,请在单线程项目中执行。如果您相信并发会帮助您快速解决问题,那么将您完成的单线程项目暴露给并发并派生测试来验证您的信念。我建议以线程不必共享工作的方式公开并发。

【讨论】:

    【解决方案2】:

    Pthread 原语通常相当有效;阻塞的东西在阻塞时通常不消耗或可以忽略不计的 CPU 时间。如果您遇到性能问题,请先查看其他地方。

    不用担心调度策略。如果您的应用程序设计为一次只能运行一个线程,那么您将失去最初线程化的大部分好处,同时增加所有成本。 (而且,如果您不承担所有成本,例如因为一次只运行一个线程而锁定共享变量,那么您就是在自找麻烦。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-19
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多