Скачиваний:
22
Добавлен:
28.06.2014
Размер:
5.82 Кб
Скачать
#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;
}
Соседние файлы в папке lab4