r/vsbnuda•
Kongy1

[APPS] Threads - Radek

// ***********************************************************************
//
// Demo program pro vyuku predmetu APPS (09/2011)
// Petr Olivka, katedra informatiky, FEI, VSB-TU Ostrava
// email:petr.olivka@vsb.cz
//
// Priklad pouzit vlaken v OS Windows
// Pro overeni paralelismu je nutno mit alespon dvoujadrovy procesor
//
// ***********************************************************************

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

#define TYP int

int DELKA = 20;
TYP *POLE, *LEFT, *RIGHT;
TYP MAX1 = 0, MAX2 = 0, MAX3 = 0;

// funkce rand() je pouze 16 bitova
// rand32 vraci 32 bitove nahodne cislo
int rand32()
{
    return rand() * RAND_MAX + rand();
}

void fillArray(int *array, int size) {
	for (int i = 0; i < size; i++)
	{
		array[i] = rand32() % DELKA;
		//array[i] = i;
	}
}

void fillArray2(TYP *array, TYP from, TYP to) {
	for (long i = from; i < to; i++)
	{
		array[i] = rand32()%100+1;
		//array[i] = i;
	}
}

void printArray(TYP *array, int size) {
	for (int i = 0; i < size; i++)
	{
		printf("%d\n", array[i]);
	}
}

// funkce pro nalezeni nejvetsiho cisla v useku pole
// od leveho (vcetne) az k pravemu prvku
TYP hledej_max( int levy, int pravy, TYP *pole )
{
	TYP nejvetsi = pole[ levy ];
	for ( int i = levy + 1; i < pravy; i++ )
		if ( nejvetsi < pole[ i ] )
			nejvetsi = pole[ i ];
	return nejvetsi;
}

// Pouziti globalnich promennych zjednodusuje ukazku pouziti vlaken.
// Neni ovsem programatorsky spravne!
// Globalni promenne: DELKA - pocet prvku na ktere odkazuje POLE


void swap(int *a, int *b) {
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

void bubbleSort(int *array, int size) {
	for (int i = 0; i < size - 1; i++)
	{
		for (int j = 0; j < size - i - 1; j++)
		{
			if (array[j] < array[j + 1])
			{
				swap(&array[j], &array[j + 1]);
			}
		}
	}
}

void bubbleSort2(int *array, int l, int r) {
	for (int i = l; i < r - 1; i++)
	{
		for (int j = l; j < r - i - 1; j++)
		{
			if (array[j] > array[j + 1])
			{
				swap(&array[j], &array[j + 1]);
			}
		}
	}
}

// vlakno A bude hledat maximalni prvek pole mezi prvkem 0 a DELKA/2
// vysledek ulozi do globalni promenne MAX1
DWORD WINAPI vlaknoA( LPVOID )
{
	printf( "Startuje vlakno A\n" );
    MAX1 = hledej_max( 0, DELKA / 3, POLE );
	return 0;
}

DWORD WINAPI vlaknoB( LPVOID )
{
	printf( "Startuje vlakno B\n" );
    MAX2 = hledej_max( DELKA / 3, 2*DELKA/3, POLE );
	return 0;
}

DWORD WINAPI vlaknoC(LPVOID)
{
	printf("Startuje vlakno C\n");
	MAX3 = hledej_max(2*DELKA/3, DELKA, POLE);
	return 0;
}

DWORD WINAPI vlaknoD(LPVOID)
{
	printf("Startuje vlakno D\n");
	MAX1 = hledej_max(0, DELKA/2, POLE);
	return 0;
}

DWORD WINAPI vlaknoE(LPVOID)
{
	printf("Startuje vlakno E\n");
	MAX2 = hledej_max(DELKA / 2, DELKA, POLE);
	return 0;
}

DWORD WINAPI vlaknoF(LPVOID)
{
	printf("Startuje vlakno F\n");
	MAX1 = hledej_max(0, DELKA, POLE);
	return 0;
}

DWORD WINAPI vlaknoNaplneni(LPVOID param)
{
	int *a = (int*)param;
	int l = a[0];
	int r = a[1];
	printf("Startuje vlakno F - %d - %d\n",l,r);
	fillArray2(POLE, l, r);
	return 0;
}

DWORD WINAPI vlaknoSetrizeni(LPVOID param)
{
	int *a = (int*)param;
	int l = a[0];
	int r = a[1];
	printf("Startuje vlakno SETRIZENI - %d - %d\n", l, r);
	return 0;
}

DWORD WINAPI vlaknoBubble(LPVOID param)
{
	int l = (int)param;
	printf("Startuje vlakno SETRIZENI - %d\n", l);
	if (l == 1)
	{
		bubbleSort(LEFT, DELKA / 2);
	}
	else {
		bubbleSort(RIGHT,DELKA - DELKA / 2);
	}
	return 0;
}

void split(int *l, int *p, int *arr, int size) {
	for (int i = 0; i < size / 2; i++)
	{
		l[i] = arr[i];
	}

	int pom = 0;
	for (int i = size / 2; i < size; i++)
	{
		p[pom++] = arr[i];
	}
}

void merge(int* l, int* p, int *arr, int lSize, int rSize) {
	int i, j, k;
	i = 0;
	j = 0;
	k = 0;

	while (i < lSize && j < rSize)
	{
		if (l[i] > p[j])
		{
			arr[k++] = l[i++];
		}
		else if (l[i] < p[j])
		{
			arr[k++] = p[j++];
		}
		else
		{
			arr[k++] = l[i++];
			arr[k++] = p[j++];
		}
	}

	while (i < lSize)
	{
		arr[k++] = l[i++];
	}

	while (j < rSize)
	{
		arr[k++] = p[j++];
	}

}


// vypocet casoveho intervalu v milisekundach
int kolik_ms( LPFILETIME pred, LPFILETIME po )
{
	hyper pred64b = pred->dwHighDateTime;
	pred64b = ( pred64b << 32 ) | pred->dwLowDateTime;
	hyper po64b = po->dwHighDateTime;
	po64b = ( po64b << 32 ) | po->dwLowDateTime;
	// konverze 100ns -> 1ms
	return ( int ) ( ( po64b - pred64b ) / 10000 );
}

int main( int na, char **arg )
{
	// pri zpusteni je nutno zadat argument udavajici delku pole 
	// nahodne vygenerovanych cisel
	/*if ( na != 2 ) 
	{ 
		printf( "Zadej pocet prvku, minimalne 1000000\n" ); 
		return 0; 
	}
	DELKA = atoi( arg[ 1 ] );
	if ( DELKA < 1000000 ) 
	{ 
		printf( "Pocet prvku musi byt minimalne 1000000\n" ); 
		return 0; 
	}*/

	// alokace pole
	

	// inicializace generatoru nahodnych cisel
	

	
	/*for ( int i = 0; i < DELKA; i++ )
	{
		POLE[ i ] = rand32() % ( DELKA * 10 );
		if ( !( i % 10000000 ) ) printf( "." ); 
	}*/

	/*printf( "\nHledani nejvetsiho prvku pomoci 2 vlaken...\n" );
	HANDLE p1, p2;
	FILETIME cas_pred, cas_po;

	// zaznamenani casu pred zapocetim hledani
	GetSystemTimeAsFileTime ( &cas_pred );

	// vytvoreni dvou vlaken
	p1 = CreateThread( 0, 0, vlaknoA, 0, 0, 0 );
	p2 = CreateThread( 0, 0, vlaknoB, 0, 0, 0 );

	// cekani na ukonceni vlaken
	WaitForSingleObject( p1, INFINITE );
	WaitForSingleObject( p2, INFINITE );

	// zaznam casu po ukonceni prace obou vlaken
	GetSystemTimeAsFileTime( &cas_po );

	printf( "Nalezene maximum je %d\n", max( MAX1, MAX2 ) );
	printf( "Cas hledani byl %d [ms]\n", kolik_ms( &cas_pred, &cas_po ) );

	printf( "Hledani nejvetsiho prvku pomoci 1 vlakna...\n" );
	GetSystemTimeAsFileTime( &cas_pred );

	// hledani jednim vlaknem
	TYP M = hledej_max( 0, DELKA, POLE );

	GetSystemTimeAsFileTime( &cas_po );

	printf( "Nalezene maximum je %d\n", M );
	printf( "Cas hledani byl %d [ms]\n", kolik_ms( &cas_pred, &cas_po ) );*/
	POLE = new TYP[DELKA];
	LEFT = new TYP[DELKA / 2];
	RIGHT = new TYP[DELKA - DELKA / 2];
	if (!POLE)
	{
		printf("Nelze alokovat pamet!\n");
		return 1;
	}


	srand((int)time(NULL));

	/*
	printf("Generuji nahodna cisla\n");
	fillArray(POLE, DELKA);

	HANDLE p1, p2, p3;
	FILETIME cas_pred, cas_po;

	GetSystemTimeAsFileTime(&cas_pred);

	p1 = CreateThread(0, 0, vlaknoA, 0, 0, 0);
	p2 = CreateThread(0, 0, vlaknoB, 0, 0, 0);
	p3 = CreateThread(0, 0, vlaknoC, 0, 0, 0);

	WaitForSingleObject(p1, INFINITE);
	WaitForSingleObject(p2, INFINITE);
	WaitForSingleObject(p3, INFINITE);

	GetSystemTimeAsFileTime(&cas_po);

	printf("Nalezene maximum je %d\n", max(MAX1, max(MAX2,MAX3)));
	printf("Cas hledani byl %d [ms]\n", kolik_ms(&cas_pred, &cas_po));

	GetSystemTimeAsFileTime(&cas_pred);

	p1 = CreateThread(0, 0, vlaknoD, 0, 0, 0);
	p2 = CreateThread(0, 0, vlaknoE, 0, 0, 0);

	WaitForSingleObject(p1, INFINITE);
	WaitForSingleObject(p2, INFINITE);

	GetSystemTimeAsFileTime(&cas_po);

	printf("Nalezene maximum je %d\n", max(MAX1, MAX2));
	printf("Cas hledani byl %d [ms]\n", kolik_ms(&cas_pred, &cas_po));

	GetSystemTimeAsFileTime(&cas_pred);

	p1 = CreateThread(0, 0, vlaknoF, 0, 0, 0);

	WaitForSingleObject(p1, INFINITE);

	GetSystemTimeAsFileTime(&cas_po);

	printf("Nalezene maximum je %d\n", MAX1);
	printf("Cas hledani byl %d [ms]\n", kolik_ms(&cas_pred, &cas_po));
	*/

	/*printf("Generuji nahodna cisla\n");
	fillArray(POLE, DELKA);
	FILETIME cas_pred, cas_po;
	int casVms;

	GetSystemTimeAsFileTime(&cas_pred);

	printf("Tridim...\n");
	bubbleSort(POLE, DELKA);

	GetSystemTimeAsFileTime(&cas_po);

	casVms = kolik_ms(&cas_pred, &cas_po);
	printArray(POLE, 50);
	printf("Cas hledani byl %d [ms]\n", casVms);*/


	/*
	HANDLE p1, p2, p3, p4;
	FILETIME cas_pred, cas_po;

	GetSystemTimeAsFileTime(&cas_pred);

	int pom[2];
	int pom2[2];
	int pom3[2];
	int pom4[2];

	pom[0] = 0;
	pom[1] = DELKA/4;
	p1 = CreateThread(0, 0, vlaknoNaplneni, (LPVOID)pom, 0, 0);

	pom2[0] = DELKA / 4;
	pom2[1] = 2*(DELKA / 4);
	p2 = CreateThread(0, 0, vlaknoNaplneni, (LPVOID)pom2, 0, 0);

	pom3[0] = 2 * (DELKA / 4);
	pom3[1] = 3 * (DELKA / 4);
	p3 = CreateThread(0, 0, vlaknoNaplneni, (LPVOID)pom3, 0, 0);

	pom4[0] = 3 * (DELKA / 4);
	pom4[1] = DELKA;
	p4 = CreateThread(0, 0, vlaknoNaplneni, (LPVOID)pom4, 0, 0);

	WaitForSingleObject(p1, INFINITE);
	WaitForSingleObject(p2, INFINITE);
	WaitForSingleObject(p3, INFINITE);
	WaitForSingleObject(p4, INFINITE);

	GetSystemTimeAsFileTime(&cas_po);

	printArray(POLE, 20);
	printf("Cas naplneni byl %d [ms]\n", kolik_ms(&cas_pred, &cas_po));

	GetSystemTimeAsFileTime(&cas_pred);

	fillArray2(POLE, 0, DELKA);

	GetSystemTimeAsFileTime(&cas_po);
	printf("1 vlakno - Cas naplneni byl %d [ms]\n", kolik_ms(&cas_pred, &cas_po));

	*/

	HANDLE p1, p2;
	FILETIME cas_pred, cas_po;

	fillArray(POLE, DELKA);
	//printArray(POLE, DELKA);
	split(LEFT, RIGHT, POLE, DELKA);

	p1 = CreateThread(0, 0, vlaknoBubble, (LPVOID)1, 0, 0);
	p2 = CreateThread(0, 0, vlaknoBubble, (LPVOID)0, 0, 0);

	GetSystemTimeAsFileTime(&cas_pred);
	
	WaitForSingleObject(p1, INFINITE);
	WaitForSingleObject(p2, INFINITE);

	GetSystemTimeAsFileTime(&cas_po);

	
	merge(LEFT, RIGHT, POLE, DELKA / 2, DELKA - DELKA / 2);
	

	

	printf("SETRIZENO\n");
	printArray(POLE, DELKA);
	printf("Cas setrizeni byl %d [ms]\n", kolik_ms(&cas_pred, &cas_po));
	

}

Posted Dec 2, 2015, 10:39 PM UTC

10
Loading comments…