Добавил:
Tushkan
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define MAX_THREADS 4
FILE *f_matrix, *f_time, *f_res;
HANDLE hThreadArray[MAX_THREADS];
DWORD WINAPI PrimsAlgorithm( LPVOID );
int* matr;
int Size;
struct Edge { double Pred; int Succ; };
int* Vnew;
int weight;
int g_min = 99;
Edge g_edge;
//---------------------------------------------------------
// Defines synchronization info structure. All threads will
// use the same instance of this struct to implement randezvous/
// barrier synchronization pattern.
struct SyncInfo
{
SyncInfo(int threadsCount) : Awaiting(threadsCount), ThreadsCount(threadsCount), Semaphore(::CreateSemaphore(0, 0, 1024, 0)) {};
~SyncInfo() { ::CloseHandle(this->Semaphore); }
volatile unsigned int Awaiting; // how many threads still have to complete their iteration
const int ThreadsCount;
const HANDLE Semaphore;
};
//---------------------------------------------------------
// Thread-specific parameters. Note that Sync is a reference
// (i.e. all threads share the same SyncInfo instance).
struct ThreadParams
{
ThreadParams(SyncInfo &sync, int ordinal) : Sync(sync), Ordinal(ordinal) {};
SyncInfo &Sync;
const int Ordinal;
};
//---------------------------------------------------------
// Called at the end of each itaration, it will "randezvous"
// (meet) all the threads before returning (so that next
// iteration can begin). In practical terms this function
// will block until all the other threads finish their iteration.
static void RandezvousOthers(SyncInfo &sync)
{
if (0 == ::InterlockedDecrement(&(sync.Awaiting))) {
sync.Awaiting = sync.ThreadsCount;
Vnew[g_edge.Succ] = g_edge.Pred;
weight += g_min;
g_min = 99;
::ReleaseSemaphore(sync.Semaphore, sync.ThreadsCount - 1, 0); // "ThreadsCount - 1" because this last thread will not block on semaphore
}
else {
::WaitForSingleObject(sync.Semaphore, INFINITE);
}
}
void ProcessInitialization()
{
int i,j;
f_matrix = fopen("C:\\Users\\main\\Documents\\Visual Studio 2010\\Projects\\lab2\\Matrices\\graph20000.txt", "r");
fscanf(f_matrix, "%d\n", &Size);
matr = (int*)malloc(Size*Size*sizeof(int));
for (i = 0; i < Size; i++)
{
int buf;
matr[i*Size + i] = 99;
for (j = i + 1; j < Size; j++)
{
fscanf(f_matrix, "%i", &buf);
matr[i*Size + j] = buf;
matr[j*Size + i] = buf;
}
}
Vnew = new int [Size];
for (int i = 1; i < Size; i++)
{
Vnew[i] = -1;
}
Vnew[0] = 0;
weight = 0;
//for (i = 0; i < RowNum; i++)
//{
// for (int j = 0; j < Size; j++)
// {
// printf("%d ", matr[i*Size + j]);
// }
// printf("\n");
//}
}
CRITICAL_SECTION CriticalSection;
SyncInfo sync(MAX_THREADS);
DWORD WINAPI PrimsAlgorithm(LPVOID lpParam)
{
int min;
int pred = 0;
int succ = 0;
int threadNumber = *((int *)(lpParam));
for (int k = 0; k < Size - 1; k++)
{
min = 99;
for (int i = threadNumber; i < Size; i+= MAX_THREADS)
{
if (Vnew[i] != -1)
{
for (int j = 0; j < Size; j++)
{
if (Vnew[j] == -1)
{
if (matr[i*Size + j] < min)
{
min = matr[i*Size + j];
succ = j;
pred = i;
}
}
}
}
}
printf("%d \n",k);
// Request ownership of the critical section.
EnterCriticalSection(&CriticalSection);
// Access the shared resource.
if (min < g_min)
{
g_min = min;
g_edge.Pred = pred;
g_edge.Succ = succ;
}
// Release ownership of the critical section.
LeaveCriticalSection(&CriticalSection);
RandezvousOthers(sync);
}
return 0;
}
void ProcessTermination ()
{
delete [] matr;
delete [] Vnew;
}
int main(int argc,char *argv[])
{
DWORD dwThreadIdArray[MAX_THREADS];
ProcessInitialization();
::srand(::GetTickCount());
__int64 freq, start,end,diff;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
QueryPerformanceCounter((LARGE_INTEGER*)&start);
if (!InitializeCriticalSectionAndSpinCount(&CriticalSection,0x00000400))
return 0;
int Ordinal[MAX_THREADS];
for( int i=0; i<MAX_THREADS; i++ )
{
Ordinal[i] = i;
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
PrimsAlgorithm, // thread function name
&Ordinal[i], // argument to thread function
0, // use default creation flags
&dwThreadIdArray[i]); // returns the thread identifier
if (hThreadArray[i] == NULL)
{
printf("Error creating thread\n");
return 0;
}
}
WaitForMultipleObjects(MAX_THREADS, hThreadArray, FALSE, INFINITE);
QueryPerformanceCounter((LARGE_INTEGER*)&end);
DeleteCriticalSection(&CriticalSection);
diff = ((end - start) * 1000) / freq;
unsigned int milliseconds = (unsigned int)(diff & 0xffffffff);
f_res = fopen("C:\\Users\\main\\Documents\\Visual Studio 2010\\Projects\\lab2\\result.txt", "w");
int k = 0;
int j =0;
for (int i=0; i<Size; i++)
{
fprintf(f_res,"%d %d\n", i, Vnew[i]);
//fprintf(f_res,"%c %c\n", static_cast<char>(i + 'A'), static_cast<char>(Vnew[i] + 'A'));
}
fclose(f_res);
f_time = fopen("C:\\Users\\main\\Documents\\Visual Studio 2010\\Projects\\lab2\\Time2.txt", "a+");
fprintf(f_time, "Number of threads: %d\n Size of Matrix: %d\n Time of execution: %f\n\n", MAX_THREADS, Size, (double)milliseconds/1000);
fclose(f_time);
return 0;
}