【问题标题】:Bug in multithreaded program (works slowly)多线程程序中的错误(工作缓慢)
【发布时间】:2014-04-04 15:53:27
【问题描述】:

我必须编写一个多线程程序(用旋转方法求解方程组)。我的程序给出了正确的答案。但是当我创建更多线程时它运行得更慢。有人能帮我解决这个问题吗? 我的部分代码:

typedef struct DATA
 {
double *a; 
int n;
int num_thr; 
int total_thr;
int num_row1;
int num_row2;
double cos;
double sin; 
 }  DATA;


 void synchronize(int total_threads)
  {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t condvar_in = PTHREAD_COND_INITIALIZER;
static pthread_cond_t condvar_out = PTHREAD_COND_INITIALIZER;
static int threads_in = 0;
static int threads_out = 0;

pthread_mutex_lock(&mutex);

threads_in++;
if (threads_in >= total_threads)
{
    threads_out = 0;
    pthread_cond_broadcast(&condvar_in);
} else
    while (threads_in < total_threads)
        pthread_cond_wait(&condvar_in,&mutex);

threads_out++;
if (threads_out >= total_threads)
{
    threads_in = 0;
    pthread_cond_broadcast(&condvar_out);
} else
    while (threads_out < total_threads)
        pthread_cond_wait(&condvar_out,&mutex);

pthread_mutex_unlock(&mutex);
 }

void rotation (double *a,int n, int num_thr,int total_thr,int num_row1,int num_row2,double cos,double sin)
{
int k;
double m;
int first;

first=n-1-num_thr;
for (k=first;k>=num_row1;k=k-total_thr)
{
    m=a[num_row1*n+k];
    a[num_row1*n+k]=cos*a[num_row1*n+k]+sin*a[num_row2*n+k];
    a[num_row2*n+k]=-sin*m+cos*a[num_row2*n+k];

}
    synchronize (total_thr);


 }
void * rotation_threaded(void *pa)
 {

DATA *data=(DATA*)pa ;
rotation(data->a,data->n,data->num_thr,data->total_thr,data->num_row1,data->num_row2,data->cos,data->sin);
return 0;
 }



int main(int argc, char * argv[])
 {
................


    for(i=0;i<n;i++)
{
    for(j=i+1;j<n;j++)
    {
        n1=a[j*n+i];
            m=a[i*n+i];

            cos=m/sqrt(m*m+n1*n1);
            sin=n1/sqrt(m*m+n1*n1);
            for (t=0;t<total_thr;t++)
            {
                data[t].n=n;
                data[t].a=a;
                data[t].total_thr=total_thr;
                data[t].num_thr=t;
                data[t].num_row1=i;
                data[t].num_row2=j;
                data[t].cos=cos;
                data[t].sin=sin;
            }

            for (k=0;k<total_thr;k++)
            {
                if (pthread_create (threads+k,0,rotation_threaded,data+k))                  {
                    printf (" Couldn't create %d thread",k);
                    return 3;
                }

            }
            for (k=0;k<total_thr;k++)
            {

                if (pthread_join (threads[k],0))
                printf ("Mistake %d \n",k);
            }
            h=b[i];
            b[i]=cos*b[i]+sin*b[j];
            b[j]=-sin*h+cos*b[j];
    } 
}

..............
  }

【问题讨论】:

  • 不相关,但您不应该在全局范围内使用带有前导下划线的名称,或者在任何位置使用前导下划线后跟大写字母的名称,因为这些(以及更多变体)由 C 规范保留.当涉及到结构时,您可以为结构 typedef 使用相同的名称。
  • 也无关,但您的代码可以使用一些格式。不要将缩进与空格和制表符混合(看起来你可能已经这样做了)。并添加一些 cmets,以便更容易理解代码的作用。当发布到像 SO 这样的国际网站时,请尝试将字符串和名称翻译成英文,我怀疑这里的许多人都懂俄语(或相关语言)。
  • 欢迎来到 SO。我的印象是这对于这个网站来说太宽泛了。您有具体的技术问题吗?
  • 没有单个注释的代码;祝你好运。
  • 没什么具体的,只是不明白为什么我的程序在线程较多的情况下运行缓慢。

标签: c multithreading time pthreads


【解决方案1】:

回答具体问题:因为您的线程在尝试获取锁和等待条件变量上花费的时间比实际工作要多。多线程不是一个免费获得更多权力的方案,如果您必须不断获取高度竞争的锁,您将为此付出严重的开销惩罚。您拥有的线程越多,它们争夺锁的次数就越多,并且在另一个线程持有锁时花费越多。

为了解决这个问题:尝试仅在必要时同步数据。将大量更改排队,和/或一次做更多工作以实际利用 CPU 上的线程时间。同步时,尽量只保持最短的绝对必要时间。

最后但并非最不重要的一点:更多线程可能并不总是更好。如果您有多个线程在一个作业队列上运行,通常最好只启动与逻辑 CPU 内核一样多的线程,这样线程就不必争夺单个内核。不过,与所有事情一样,正确的分析会告诉您问题出在哪里。

【讨论】:

    【解决方案2】:

    据我所知,您为每个 (i,j) 对重新创建线程,然后等待所有线程完成。

    在开始时创建线程并让它们等待某个条件可能更有意义。然后可以重复使用线程。

    您似乎还在为每次迭代中的每个线程复制大量不变的信息(这可能不是减速的原因,但为什么不明确什么是可变的)。 data 中每个线程唯一不同的信息是num_thrna 的值永远不会改变,cossinij 的值可以保存在 for-t 循环之外。

    synchronize 方法有什么用。似乎要等待所有线程通过threads_in“障碍”,然后通过threads_out“障碍”,但它保护的是什么?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-09
      • 2017-04-18
      • 2015-06-09
      相关资源
      最近更新 更多