pthread程序的臭名昭着的行为

Rah*_*mar 2 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);
}
Run Code Online (Sandbox Code Playgroud)

是的,我错误地将第二个长长的可变吊舱启动到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开关

Dav*_*rtz 5

您正在看到由近距离以相同方式引起sumpod初始化的错误共享.这导致他们共享缓存行.

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

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

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