我编写了这两个版本的代码来计算两个数组的点积运算。每个长度都是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<=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。
始终检查循环的边界条件,尤其是数组访问。
关于c - 并行和顺序点积程序不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20708184/