Добавил:
Tushkan
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <conio.h>
#include <stdlib.h>
using namespace std;
#define MAX_THREADS 3
#define BUF_SIZE 255
#define nRows 10
DWORD WINAPI MyThreadFunction( LPVOID lpParam );
void ErrorHandler(LPTSTR lpszFunction);
void ConsoleOutput(double _time);
void FileOutput();
int nRowsOnProc;
double **partMatr;//, **partMu;
double *buf;
int *map;
long double det;
FILE *U;
HANDLE _mutex = CreateMutex(NULL, FALSE, NULL);
struct SyncInfo
{
SyncInfo(int threadsCount) : Awaiting(threadsCount), ThreadsCount(threadsCount), Semaphore(::CreateSemaphore(0, 0, 1024, 0)) {};
~SyncInfo() { ::CloseHandle(this->Semaphore); }
volatile unsigned int Awaiting;
const int ThreadsCount;
const HANDLE Semaphore;
};
static void RandezvousOthers(SyncInfo &sync)
{
if (0 == ::InterlockedDecrement(&(sync.Awaiting))) {
sync.Awaiting = sync.ThreadsCount;
::ReleaseSemaphore(sync.Semaphore, sync.ThreadsCount - 1, 0);
}
else {
::WaitForSingleObject(sync.Semaphore, INFINITE);
}
}
SyncInfo sync(MAX_THREADS);
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
_cputs("Begin\n");
nRowsOnProc=1 + nRows / MAX_THREADS;
partMatr=new double*[nRows];
//partMu=new double*[nRowsOnProc];
buf=new double[nRows];
map=new int[nRows];
for(int i=0; i<nRows; i++)
{
partMatr[i]=new double[nRows];
map[i]=i % MAX_THREADS;
}
::srand(::GetTickCount());
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nRows; j++)
{
partMatr[i][j] = -100 + rand() % 200;
//partMatr[i][j] /= 1000;
}
}
__int64 freq, start,end,diff;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
QueryPerformanceCounter((LARGE_INTEGER*)&start);
_cputs("In process...\n");
int thNumbers[MAX_THREADS];
for( int i=0; i<MAX_THREADS; i++ )
{
thNumbers[i] = i;
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction,
&thNumbers[i],
0, // use default creation flags
&dwThreadIdArray[i]); // returns the thread identifier
if (hThreadArray[i] == NULL)
{
ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
}
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
det = 1;
for(int i = 0; i < nRows; i++)
det *= partMatr[i][i];
QueryPerformanceCounter((LARGE_INTEGER*)&end);
diff = ((end - start) * 1000) / freq;
unsigned int milliseconds = (unsigned int)(diff & 0xffffffff);
FileOutput();
ConsoleOutput((double)milliseconds/1000);
for(int i=0; i<MAX_THREADS; i++)
{
CloseHandle(hThreadArray[i]);
}
CloseHandle(_mutex);
_getch();
return 0;
}
void FileOutput()
{
fopen_s(&U, "u.txt", "w");
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nRows; j++)
if(j >= i)
fprintf(U, "%f ", partMatr[i][j]);
else
fprintf(U, "0 ");
fprintf(U, "\n");
delete [] partMatr[i];
}
fclose(U);
}
void ConsoleOutput(double _time)
{
_cprintf("Det = %Lf\n", det);
_cprintf("Time = %f\n", _time);
_cputs("End. Press Enter...");
}
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
int th;
th = *((int *)(lpParam));
double mu;
for (int k = 0; k < nRows - 1; k++)
{
for (int i =0; i < nRows; i++)
{
if (map[i] == th)
{
mu = partMatr[i / MAX_THREADS][k] / partMatr[k / MAX_THREADS][k];
for (int j = k; j < nRows; j++)
partMatr[i / MAX_THREADS][j] -= mu * partMatr[k / MAX_THREADS][j];
}
}
RandezvousOthers(sync);
}
return 0;
}
void ErrorHandler(LPTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}