C ++矩阵乘法与多线程和信号量

时间:2015-05-14 17:38:22

标签: c++ multithreading semaphore

我编写了一个执行两个矩阵相乘的程序。当我执行它时,它有时会工作,有时它不起作用,有时一半的答案是正确的。我认为线程和信号量的使用存在问题。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <mutex>
#include <thread>

//NOTE: THIS CODE NEEDS C++11 COMPILER TO COMPILE.

using namespace std;
int const size = 4;
mutex mtx[size][size];
thread myThread[size];


void MatrixMultiplication(int const * const * matrixA, int const * const * matrixB,int** matrixC, int row, int col, int i){
    mtx[row][col].lock();
    matrixC[row][col] += matrixA[row][i]*matrixB[i][col];
    mtx[row][col].unlock();
}

int main()
{
    int** matrixA;
    int** matrixB;
    int** matrixC;

    matrixA = new int*[size];
    matrixB = new int*[size];
    matrixC = new int*[size];

    for(int i = 0; i<size; i++){
        matrixA[i] = new int[size];
        matrixB[i] = new int[size];
        matrixC[i] = new int[size];
    }

    //WE ARE INITIALIZING MATRICES.
    int count = 1;
    for(int i = 0; i<size; i++){
        for(int j = 0; j<size; j++){
            matrixA[i][j] = count;
            matrixB[i][j] = count;
            count++;
        }
    }


    for(int row=0; row<size; row++){
        for(int col=0; col<size;col++){
            for(int i=0;i<size;i++){
                myThread[i] = thread(MatrixMultiplication, matrixA, matrixB, matrixC, row, col, i);
                myThread[i].join();
            }
        }
    }


    for(int i = 0; i<size; i++){
        for(int j = 0; j<size; j++){
            cout<<matrixC[i][j]<<"  ";
        }
        cout<<endl;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:1)

据我所知,这里有两件事情出了问题。

   for(int row=0; row<size; row++){
        for(int col=0; col<size;col++){
            for(int i=0;i<size;i++){
                myThread[i] = thread(MatrixMultiplication, matrixA, matrixB, matrixC, row, col, i);
                myThread[i].join();
            }
        }
    }

应该是

   for(int row=0; row<size; row++){
        for(int col=0; col<size;col++){
            for(int i=0;i<size;i++){
                myThread[i] = thread(MatrixMultiplication, matrixA, matrixB, matrixC, row, col, i);
            }
        }
    }

for(int row=0; row<size; row++){
   for(int col=0; col<size;col++){
      for(int i=0;i<size;i++){
         myThread[i].join();
      }
   }
}

这样你首先要创建一堆计算。然后进行实际计算。然而,这仍然不是你应该采取的方式。一个帖子应该有合理的工作量。

所以在你继续这样做之前,请允许我解释一下线程。一个线程同时执行不同的工作 。由于它是在同一时间执行的,因此您永远不能让线程访问可能由另一个线程写入的数据。否则,你可能会得到一半写入的数据(所谓的竞争条件)。

因此,std::thread()调用将始终复制它给出的所有参数。即使它是一个指针。你可以做的是让每个线程在一个单独的线程上为每一列进行计算。但是,为了做到这一点,我建议创建一个column结构或类。并通过std::ref传递给线程。使用std::ref传递将阻止数据被复制。