// Блочное умножение.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <pthread.h>
#include <iostream>
#include <locale.h>
#include <time.h>
using namespace std;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
int n=4;
int m=4;
int blN = 2, blM = 2;
int p = blN*blM;
pthread_t **threads;
int *b, *c;
int **a;
long times = clock();
struct Block
{
int begN;
int endN;
int begM;
int endM;
};
void multiple(int begN, int endN, int begM, int endM)
{
int *tmp = (int*)malloc((endN-begN)*sizeof(int));
for (int i = 0; i < endN - begN; i++)
tmp[i] = 0;
for (int i = begN; i < endN; i++)
for (int j = begM; j < endM; j++)
tmp[i - begN]+= a[i][j] * b[j];
for (int j = begN; j < endN; j++)
{
pthread_mutex_lock(&mut);
c[j] += tmp[j - begN];
cout << "c[" << j << "]=" << c[j] << "\n";
pthread_mutex_unlock(&mut);
}
delete[] tmp;
}
void *process_function(void *pa)
{
Block bl = *((struct Block *)pa);
multiple(bl.begN, bl.endN, bl.begM, bl.endM);
delete (struct Block *)pa;
return 0;
}
int main()
{
setlocale(LC_ALL, "Rus");
a = (int**)malloc(n*sizeof(int));
for (int i = 0; i < n; i++)
a[i] = (int*)malloc(m*sizeof(int));
b = (int*)malloc(m*sizeof(int));
c = (int*)malloc(n*sizeof(int));
threads = new pthread_t*[blN];
for (int i = 0; i<blN; i++)
threads[i] = new pthread_t[blM];
for (int i = 0; i < n; i++)
c[i] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
a[i][j] = rand() % 5;
cout << a[i][j] << ' ';
if (j == m - 1) cout << "\n";
}
cout << endl;
for (int i = 0; i < m; i++)
{
b[i] = rand() % 5;
cout << b[i] << "\n";
}
cout << endl;
int locM = m / blM;
int locN = n / blN;
int ostM = m%blM;
int ostN = n%blN;
int endM = 0, endN = 0;
for (int i = 0; i < blN; i++)
{
Block *bl = new Block;
bl->begN = endN;
if (ostN > 0)
bl->endN = bl->begN + locN + 1;
else
bl->endN = bl->begN + locN;
endN = bl->endN;
endM = 0;
ostM = n%blM;
for (int j = 0; j < blM; j++)
{
Block *block = new Block;
block = bl;
block->begM = endM;
if (ostM > 0)
block->endM = block->begM + locM + 1;
else
block->endM = block->begM + locM;
endM = block->endM;
pthread_create(&threads[i][j], NULL, process_function, block);
}
free(bl);
}
for (int i = 0; i<blN; i++)
for (int j = 0; j<blM; j++)
if (pthread_join(threads[i][j], NULL))
fprintf(stderr, "wait thread #d!\n", i,j);
cout << "Результат: \n";
for (int i = 0; i<n; i++)
cout << c[i] << '\n';
cout << "Время выполнения:" << times << endl;
for (int i = 0; i < n; i++)
free(a[i]);
free(a);
free(b);
free(c);
return 0;
}