Использование pthread для выполнения умножения матриц - PullRequest
4 голосов
/ 15 марта 2010

У меня есть обе матрицы, содержащие только единицы, и каждый массив имеет 500 строк и столбцов . Итак, результирующая матрица должна быть матрицей всех элементов, имеющих значение 500 . Но я получаю res_mat [0] [0] = 5000 . Даже другие элементы также 5000. Почему ?

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

#define ROWS 500
#define COLUMNS 500
#define N_THREADS 10

int mat1[ROWS][COLUMNS],mat2[ROWS][COLUMNS],res_mat[ROWS][COLUMNS];

void *mult_thread(void *t)
{   
    /*This function calculates 50 ROWS of the matrix*/

    int starting_row;
    starting_row = *((int *)t);
    starting_row = 50 * starting_row;

    int i,j,k;
    for (i = starting_row;i<starting_row+50;i++)
        for (j=0;j<COLUMNS;j++)
            for (k=0;k<ROWS;k++)
                res_mat[i][j] += (mat1[i][k] * mat2[k][j]);
    return;
}

void fill_matrix(int mat[ROWS][COLUMNS])
{
    int i,j;
    for(i=0;i<ROWS;i++)
        for(j=0;j<COLUMNS;j++)
            mat[i][j] = 1;
}

int main()
{
    int n_threads = 10; //10 threads created bcos we have 500 rows and one thread calculates 50 rows
    int j=0;
    pthread_t p[n_threads];

    fill_matrix(mat1);
    fill_matrix(mat2);
    for (j=0;j<10;j++)
        pthread_create(&p[j],NULL,mult_thread,&j);

    for (j=0;j<10;j++)
        pthread_join(p[j],NULL);

    printf("%d\n",res_mat[0][0]);
    return 0;
}

Ответы [ 2 ]

4 голосов
/ 15 марта 2010

Я не знаю, является ли это причиной вашей проблемы, но:

    pthread_create(&p[j],NULL,mult_thread,&j);

определенно сломан. Вы передаете адрес j &j. Таким образом, каждый поток получит случайное значение 0 <= initial_row <= 9, когда он действительно запускается. Вероятно, лучше просто передать <code>(void*)j и вывести его с (int)j.

Вы также никогда не инициализируете res_mat, но IIRC все равно будет инициализирован.

EDIT: Причина, по которой значение starting_row является случайным, заключается в том, что j проходит через все числа от 0 до 9 между запускаемым потоком и соединением. Таким образом, поток будет запущен в некоторой случайной точке между этими двумя и получит значение j в этой точке.

3 голосов
/ 15 марта 2010

Вы передаете указатель на j в функцию потока. Значение j, возможно, изменилось, когда поток обращается к нему. Просто передайте (void *) j и измените приведение в функции потока на starting_row = (int)t; .

...