pthread程序的臭名昭着的行为

时间:2017-03-07 09:47:17

标签: c multithreading pthreads

我是编程新手,刚开始在c语言中使用pthread。我对多线程提升性能的程度感到好奇。为了测试这个,我写了一个简单的程序来计算n位数的总和(老实说,从youtube视频中获取它)。我给了它一些真正的大数字来获得执行时间的一些值。

#include<stdio.h>
#include<pthread.h>
long long sum=0,pod=1;
void* sum_run(void* arg)
{
    long long *var_ptr=(long long *)arg;
    long long i,var=*var_ptr;
    for(i=0;i<=var;i++)
    {
        sum+=i;
    }
    pthread_exit(0);
}

void* sum_run2(void* arg)
{
    long long *var_ptr2=(long long *)arg;
    long long j,var2=*var_ptr2;
    for(j=0;j<=var2;j++)
    {
        pod+=j;
    }
    pthread_exit(0);
}

int main(void)
{
    printf("wait getting it...\n");
    long long val=999999999,val2=899999999;
    pthread_t tid[1];
    pthread_create(&tid[0],NULL,sum_run,&val);
    pthread_create(&tid[1],NULL,sum_run2,&val2);
    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);
    printf("sum1 is %lld sum2 is %lld",sum,pod);
}
是的,我错误地将第二个长长的可变吊舱启动到1,这给了我错误的结果(即超过所需的1)。所以,我纠正了我的错误并使pod = 0,并且在更改它之后出现问题我的程序的执行时间增加到比不执行相同任务而不使用pthread的程序大两倍以上。我无法想到里面发生的事情。请帮助该计划。

pod = 1 exec.time = ~2.8secs

pod = 0 exec.time = ~11.4secs

当sum = 1 pod = 1 exec.time反弹到 ~25.4secs

为什么它会因价值变化而发生变化?

另外,我发现如果一个变量为0而其他变量不是,那么它们的地址不连续。

使用Devcpp的gcc4.9.2和-pthread开关

1 个答案:

答案 0 :(得分:5)

您看到由sumpod以近距离相同的方式初始化导致的错误分享。这导致他们共享一个缓存行。

当每个线程试图修改缓存行时,它会发现另一个线程最后修改了它,并且必须调用核心间协议以将修改后的缓存行的所有权从另一个核心转移到该核心。高速缓存行将来回拨打乒乓,两个线程将以核心间总线的速度运行 - 比单个线程反复点击其L1高速缓存的速度更糟糕。这种现象称为虚假共享。

通过初始化一个而不是另一个,您可以将它们分配到不同的段中。这使得虚假共享消失了,因为它们现在相距太远而无法共享缓存线。

这个问题的一个常见解决方案是在两者之间放置一些填充变量。例如,您可以将它们放在一个结构中,long long spacing[7];之间。{/ p>