使用c中的线程乘以矩阵

时间:2015-01-09 05:50:42

标签: c matrix

我尝试使用线程来编写代码来迭代矩阵时遇到问题。我没有警告(我用std = c99 -Wall -pedantic -lpthread编译)但是当我尝试使用我的代码时,我总是遇到核心转储的问题。 我把我的代码放在这里并请求你提供任何提示,因为我真的很接近疯了。我不知道我能修复什么。我启发了this link

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include "sys/types.h"
#include "unistd.h"
#include "pthread.h"

int xA;
int yA;
int xB;
int yB;
int xC;
int yC;
int* mA;
int* mB;
int* mC;
pthread_t* thread;
int numOfThread;
int **ap = &mC;
int **A = &mA;
int **B = &mB;

int* allocResultMatrix(int xA, int yB, int *xC, int *yC){

    *xC = xA;
    *yC = yB;

    return (int *) malloc(sizeof(int) *(*xC * *yC));
}


void makeMatrix(int **ar, int x, int y){

   *ar = (int *)malloc(sizeof(int) *(x * y));
   int k = -1;
   int range = 1000;      

    for(int i = 0; i < x; i++){
        for(int j = 0; j < y; j++){
            (*ar)[++k] = rand() % range;
        }
    }  
}

void* multiply(void* slice){

    int s = (int)slice;
    int from = (s * xA)/numOfThread;
    int to = ((s+1) * xA)/numOfThread;


    for (int i = from; i < to; i++){  
        for (int j = 0; j < yB; j++){
            ap[i][j] = 0;
            for (int k = 0; k < yA; k++){
                ap[i][j] += A[i][k]*B[k][j];
            }
       }
    }
return 0;
}



void printMatrix(int *ar, int x, int y)
{
    int k = -1;

        for(int i = 0; i < x; i++){
        printf(" ");
            for(int j = 0; j < y; j++){
                printf("%9d", ar[++k]);
            }
        printf("\n");
    }  
    printf("\n");

}

int main(int argc, char* argv[]){

    if(argc == 6){


    printf("\n");



    numOfThread = atoi(argv[1]);



    if(atoi(argv[2]) > 0 && atoi(argv[2]) <= 10000 && atoi(argv[3]) > 0 && atoi(argv[3]) <= 10000 && atoi(argv[4]) > 0 && atoi(argv[4]) <= 10000 && atoi(argv[5]) > 0 && atoi(argv[5]) <= 10000 ){
        xA = atoi(argv[2]);
        yA = atoi(argv[3]);
        xB = atoi(argv[4]);
       yB = atoi(argv[5]);

    }
    else {
        printf("bad dimensions");
        return 0;
    }


    if(yA != xB){
        printf("yA should be equal with xB\n");
        return 0;
    }





    srand((unsigned)time(NULL));

    makeMatrix(&mA, xA, yA);
    printMatrix(mA, xA, yA);
    makeMatrix(&mB, xB, yB);
    printMatrix(mB, xB, yB);
    thread = (pthread_t*) malloc(numOfThread * sizeof(pthread_t));
    mC =  allocResultMatrix(xA, yB, &xC, &yC);



    for (int iterator = 1; iterator < numOfThread; iterator++){


        if (pthread_create (&thread[iterator], NULL, multiply, (void*)iterator) != 0 ){
            perror("er!\n");
        free(thread);
            return 1;
        }
}

multiply(0);

for (int i = 1; i < numOfThread; i++)
        pthread_join(thread[i], NULL);

printf("\nresult\n");
    printMatrix(mC, xC, yC);
free(thread);
}

return 0;
}

1 个答案:

答案 0 :(得分:0)

您正在分配单维数组,并尝试将其作为二维数组访问。

特别是ap[i][j]中的表达式multiplyMatrix假定您有一个指向整数数组的指针数组,但实际情况并非如此。

如果使用Klocwork或类似工具检查您的代码,您会发现ap[i][j]仅对值i=[0..xA*yB]j=0有效。

您可以分配二维数组:

int **allocate(int x, int y)
{
   int **result = malloc(x * sizeof(int*));
   for (int i = 0; i < y; i++)
   {
      result[i] = malloc(y * sizeof(int));
   }
   return result;
}

或乘以单一维度:

int s = (int)slice;
int from = (s * xA)/numOfThread;
int to = ((s+1) * xA)/numOfThread;

for (int i = from; i < to; i++)
{  
  for (int j = 0; j < yB; j++)
  {
    ap[i * yB + j] = 0;
    for (int k = 0; k < yA; k++)
    {
      ap[i * yB + j] += A[i * yA + k]*B[k * yB + j];
    }
  }
}