pthread 程序的臭名昭著的行为 [英] Notorious behaviour of pthread program

查看:41
本文介绍了pthread 程序的臭名昭著的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'am novice in programming and just started using pthread in c language.I was curious about the degree of performance improvement by multi-threading. To test this I wrote a simple program to calculates the sum of n digits(honestly, took it from youtube video). I gave it some real big numbers to get some values of execution time.

#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);
}

O 是的,我错误地将第二个 long long 变量 pod 启动为 1,这给了我错误的结果(即比所需的多 1).所以,我更正了我的错误并设置了 pod=0 并且在更改它之后出现了问题,我的程序的执行时间增加到比不使用 pthread 执行相同任务的程序还要长两倍以上.我想不出里面发生了什么.请帮助该程序.

O yeah, by mistake I initiated the second long long variable pod to 1 which gave me false result (i.e. 1 more than the desired). So , I corrected my mistake and made pod=0 and here came the PROBLEM after changing it my program's execution time increased to more than twice even larger than the program which does the same task without using pthread. I can't think of what's happening inside. Please help the program.

pod=1 exec.time=~2.8secs

pod=1 exec.time=~2.8secs

pod=0 exec.time=~11.4secs

pod=0 exec.time=~11.4secs

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

when sum=1 pod=1 exec.time bounces to ~25.4secs

为什么它会随着值的变化而变化?

Why is it shifting due to changing values?

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

Also, I found out if one variable is 0 and other's not then their addresses are not continuous.

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

Using Devcpp's gcc4.9.2 with -pthread switch

推荐答案

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

You are seeing false sharing caused by sum and pod being initialized the same way in close proximity. This causes them to share a cache line.

当每个线程试图修改缓存线时,它会发现另一个线程最后修改了它,并且必须调用内核间协议将修改后的缓存线的所有权从另一个内核转移到这个内核.缓存线将来回往复,两个线程将以内核间总线的速度运行——比单个线程重复访问其 L1 缓存的速度要差得多.这种现象称为虚假分享.

As each thread tries to modify the cache line, it will find that the other thread has modified it last and the inter-core protocol has to be invoked to transfer ownership of the modified cache line from the other core to this core. The cache line will ping-pong back and forth and the two threads will run at the speed of the inter-core bus -- much worse than the speed of a single thread repeatedly hitting its L1 cache. This phenomenon is called false sharing.

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

By initializing one and not the other, you caused them to be allocated in different segments. This made the false sharing go away as they are now too far apart to share a cache line.

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

A common solution to this problem is to put some padding variables between the two. For example, you could put them in a struct with long long spacing[7]; between them.

这篇关于pthread 程序的臭名昭著的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆