【问题标题】:parallel and sequential dotproduct programs different result并行和顺序点积程序不同的结果
【发布时间】:2013-12-20 16:42:47
【问题描述】:

我编写了这两个版本的代码,用于计算两个数组上的点积运算。每个长度为 256。这是非常简单的顺序代码:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[]){
    double sum;
    double a[256], b[256];
    int n = 256, i;
    for (i=0; i<n; i++){
        a[i] = i * 0.5;
        b[i] = i * 2.0; 
    }
    sum = 0;
    for (i=1; i<=n; i++){
        sum = sum + a[i]*b[i];
    }
    printf ("sum = %f\n", sum);
}//main

答案是5559680

但并行代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUMTHRDS 4

double sum;
double a[256], b[256];
int status;
int n=256;
pthread_t thds[NUMTHRDS];
pthread_mutex_t mutexsum;

void* dotprod(void *arg){
    int myid, i, my_first, my_last;
    double sum_local;

    myid = (int)arg;
    my_first = myid * n/NUMTHRDS;
    my_last = (myid + 1) * n/NUMTHRDS;

    sum_local = 0;
    for (i=my_first; i<=my_last; i++){
        sum_local = sum_local + a[i]*b[i];
    }

    pthread_mutex_lock(&mutexsum);
    sum = sum + sum_local;
    pthread_mutex_unlock(&mutexsum);

    pthread_exit((void*)0);
}//dotprod

int main(int argc, char* argv[]){
    int i;
    pthread_attr_t attr;
    for (i=0; i<n; i++){
        a[i] = i * 0.5;
        b[i] = i * 2.0;
    }

    pthread_mutex_init(&mutexsum, NULL);
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    for (i=0; i<NUMTHRDS; i++){
        pthread_create(&thds[i], &attr, dotprod, (void*)i);
    }

    pthread_attr_destroy(&attr);

    for(i=0; i<NUMTHRDS; i++){
        pthread_join(thds[i], (void **)&status);
    }

    printf("sum = %f \n", sum);
    pthread_mutex_destroy(&mutexsum);
    pthread_exit(NULL);

    return 0;   
}//main

答案是 5617024

我完全不明白这个区别是为了什么?

【问题讨论】:

  • for (i=1; i&lt;=n; i++) 似乎不对...
  • @OliCharlesworth - 不,没关系,因为 a[0] 和 b[0] 都等于零。
  • 这很重要,因为您超出了数组范围。
  • @alk:因为 Valgrind 只能检查动态分配的内存。
  • @OliCharlesworth:嗯,是的,忘了这个。所以valgrind --tool=exp-sgcheck 可能会完成这项工作。至少对于这个例子。

标签: c linux parallel-processing pthreads


【解决方案1】:

因一个错误而关闭。

for (i=1; i<=n; i++){

for (i=0; i<n; i++) {

for (i=my_first; i<=my_last; i++){

for (i=my_first; i<my_last; i++){

在第一个程序中,您添加了 a[256] 和 b[256],它们位于数组的末尾。 这些值很可能是 0,所以你得到了正确的答案。

在第二个程序中,您将数组的某些部分计数两次:64、128、192 和 仍在添加索引 256。

始终检查循环的边界条件,尤其是数组访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    相关资源
    最近更新 更多