【问题标题】:Using pthread to perform matrix multiplication使用 pthread 执行矩阵乘法
【发布时间】:2010-03-15 09:38:18
【问题描述】:

我的两个矩阵都只包含一个,每个数组都有 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;
}

【问题讨论】:

  • 基本上,在我的程序中,每个线程计算 50 行。我在执行函数调用 pthread_create() 时传递要计算的行的值

标签: c linux gcc pthreads unix


【解决方案1】:

我不知道这是否是您的问题的原因,但是:

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

肯定坏了。你传入的地址是 j&amp;j。所以每个线程在实际启动时都会得到一个随机值 0 (void*)j 并使用(int)j 将其取出。

您也永远不会初始化 res_mat,但 IIRC 无论如何它都会被初始化。

编辑: starting_row 的值是随机的,原因是 j 在线程启动和连接之间遍历了 0 到 9 之间的所有数字。 因此线程将在这两者之间的某个随机点启动,并在该点获取j 的值。

【讨论】:

  • 为什么在每个线程中,starting_row 的值会是 0 到 9 之间的随机值?
  • 实际上,我认为所有线程都将具有相同的 j.. 值,对吗?
  • 否,因为一旦创建了线程,您就不知道它们何时或以何种顺序被执行。在调用 pthread_create 之后,哪个线程正在执行,主线程还是刚刚创建的线程?所以你可能是对的(即所有线程都被创建然后开始执行),但这只是一种可能性
【解决方案2】:

您正在将指向 j 的指针传递给线程函数。当线程访问它时,j 的值可能已经改变。只需传递 (void *)j 并将线程函数中的强制转换更改为starting_row = (int)t;

【讨论】:

  • 那么,我该怎么做呢?只有更改 &j -> (void *)j 才会创建 SEG 故障..
  • 谢谢。我得到了它。简单而简短.. 干杯!
猜你喜欢
  • 2013-01-30
  • 1970-01-01
  • 1970-01-01
  • 2019-12-20
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
相关资源
最近更新 更多