我想使用Openmp在四个线程中分配任务。我有20x20矩阵,任务应该在四个线程之间平均分配,以下程序给出错误的结果。我认为它需要在for循环中更改参数,任何人都可以帮助我。
#include<stdio.h>
#include<omp.h>
#include "head.h"
//int sum=0;
int c[20][20];
//#include<conio.h>
int main(void) {
int A[20][20],B[20][20],C[20][20];
int i;
static int j,e;
static sum=0;
FILE *fp;
unsigned long long a,b,c,d;
int threadno;
fp=fopen("m2.txt","w");
// printf("\n%d \n",h[20][20]);
#pragma omp parallel shared(a,b,c,d)
{
threadno=omp_get_thread_num();
if(threadno==0)
{
for (i=0;i<5;i++)
{
for (j=0;j<5;j++)
{
A[i][j]=i*j;
B[i][j]=i*j;
}
}
for (i=0;i<5;i++)
{
for (j=0;j<5;j++)
{
for (e=0;e<5;e++)
{
sum+=A[i][e]*B[e][j];
C[i][j]=sum;
}
}
}
}
else if(threadno==1)
{
for (i=5;i<10;i++)
{
for (j=5;j<10;j++)
{
A[i][j]=i*j;
B[i][j]=i*j;
}
}
for (i=5;i<10;i++)
{
for (j=5;j<10;j++)
{
for (e=5;e<10;e++)
{
sum+=A[i][e]*B[e][j];
C[i][j]=sum;
}
}
}
}
else if(threadno==2)
{
for (i=10;i<15;i++)
{
for (j=10;j<15;j++)
{
A[i][j]=i*j;
B[i][j]=i*j;
}
}
for (i=10;i<15;i++)
{
for (j=10;j<15;j++)
{
for (e=10;e<15;e++)
{
sum+=A[i][e]*B[e][j];
C[i][j]=sum;
}
}
}
}
else if(threadno==3)
{
for (i=15;i<20;i++)
{
for (j=15;j<20;j++)
{
A[i][j]=i*j;
B[i][j]=i*j;
}
}
for (i=15;i<20;i++)
{
for (j=15;j<20;j++)
{
for (e=15;e<20;e++)
{
sum+=A[i][e]*B[e][j];
C[i][j]=sum;
}
}
}
}
for (i=0;i<20;i++){
for (j=0;j<20;j++) {
fprintf(fp,"%d \t",C[i][j]);
}
}
}
fclose(fp);
}
答案 0 :(得分:0)
每个线程仅在对角线周围生成25个值。这是你的意图吗?你的矩阵有400个条目,但你实际上只是初始化了4 * 25 = 100个,所以除了对角线以外,最后的打印输出大部分是垃圾。
所有线程也在没有任何锁定/同步的情况下访问变量sum
,因此您从总和中读取的值完全不确定。
如果你真的打算写一个矩阵*矩阵乘法:那么你应该首先编写你想写的三重嵌套循环。也许是这样的事情:
for (int i=0; i<20; i++) {
for (int j=0; j<20; j++) {
for (int e=0; e<20; e++) {
// some work
}
}
}
然后将4个线程之间的最外层循环分开:
for (int i = 5*omp_get_thread_num(); i < 5*(omp_get_thread_num()+1); i++) {
for (int j=0; j<20; j++) {
...
或者甚至更好地让openMP为你分工。 (我不是openMP专家,但我认为你就是这样做的。)
#pragma omp parallel
{
#pragma omp for
for (int i=0; i<20; i++) {
for (int j=0; j<20; j++) {
...
}
答案 1 :(得分:0)
使用此功能。将浮动更改为整数。
void matrix_mult_scalar_openmp(const float*A , const float* B, float* C, const int N, const int M, const int K) {
#pragma omp parallel for
for(int i=0; i<N; i++) {
for(int j=0; j<K; j++) {
float tmp = 0;
for(int l=0; l<M; l++) {
tmp += A[M*i+l]*B[K*l+j];
}
C[K*i + j] = tmp;
}
}
}
答案 2 :(得分:0)
我必须使用4个线程执行此操作,因为漫游登录它使用单个for循环,但我想在4个线程中设置任务。我根据Raxman进行了更改,一些代码是不变的因为我必须这里使用4个线程。 我修改过的代码是:
#include<stdio.h>
#include<omp.h>
#include "head.h"
//int sum=0;
int c[20][20];
//#include<conio.h>
int main(void) {
int A[20][20],B[20][20],C[20][20];
int i;
static int j,e;
int sum;
FILE *fp;
unsigned long long a,b,c,d;
int threadno;
fp=fopen("m2.txt","w");
for (i=0;i<20;i++)
{
for (j=0;j<20;j++)
{
A[i][j]=i*j;
B[i][j]=i*j;
}
}
// printf("\n%d \n",h[20][20]);
#pragma omp parallel shared(a,b,c,d)
{
threadno=omp_get_thread_num();
if(threadno==0)
{
for (i=0;i<5;i++)
{
for (j=0;j<5;j++)
{
sum=0;
for (e=0;e<5;e++)
{
sum+=A[i][e]*B[e][j];
// C[i][j]=sum;
}
C[i][j]=sum;
}
}
}
else if(threadno==1)
{
/* for (i=5;i<10;i++)
{
for (j=5;j<10;j++)
{
A[i][j]=i*j;
B[i][j]=i*j;
}
}*/
for (i=5;i<10;i++)
{
for (j=5;j<10;j++)
{
sum=0;
for (e=5;e<10;e++)
{
sum+=A[i][e]*B[e][j];
// C[i][j]=sum;
}
C[i][j]=sum;
}
}
}
else if(threadno==2)
{
/* for (i=10;i<15;i++)
{
for (j=10;j<15;j++)
{
A[i][j]=i*j;
B[i][j]=i*j;
}
}*/
for (i=10;i<15;i++)
{
for (j=10;j<15;j++)
{
sum=0;
for (e=10;e<15;e++)
{
sum+=A[i][e]*B[e][j];
}
C[i][j]=sum;
}
}
}
else if(threadno==3)
{
/* for (i=15;i<20;i++)
{
for (j=15;j<20;j++)
{
A[i][j]=i*j;
B[i][j]=i*j;
}
}*/
for (i=15;i<20;i++)
{
for (j=15;j<20;j++)
{
sum=0;
for (e=15;e<20;e++)
{
sum+=A[i][e]*B[e][j];
//C[i][j]=sum;
}
C[i][j]=sum;
}
}
}
for (i=0;i<20;i++){
for (j=0;j<20;j++) {
fprintf(fp,"%d \t",C[i][j]);
}
}
}
fclose(fp);
}