r/vsbnuda•
Kongy1

[APPS] Threads - Me

// ***********************************************************************
//
// 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

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

// 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;
}

void bubble_sort(int levy, int pravy, TYP *pole)
{
	for (int i = levy; i < pravy - 1; i++)
	{
		for (int j = levy; j < pravy - i - 1; j++)
		{
			if (pole[j + 1] < pole[j])
			{
				TYP tmp = pole[j + 1];
				pole[j + 1] = pole[j];
				pole[j] = tmp;
			}
		}
	}
}

void vypis_pole(int levy, int pravy, TYP *pole)
{
	for (int i = levy; i < pravy; i++)
		printf("%d ", pole[i]);
	printf("\n");
}

// Pouziti globalnich promennych zjednodusuje ukazku pouziti vlaken.
// Neni ovsem programatorsky spravne!
// Globalni promenne: DELKA - pocet prvku na ktere odkazuje POLE
int DELKA;
TYP *POLE, *POLE1, *POLE2;
TYP MAX1 = 0, MAX2 = 0, MAX3 = 0;

// 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;
}

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

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

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

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

void napln_pole(int pravy, int levy, TYP *pole)
{
	for (int i = pravy; i < levy; i++)
	{
		pole[i] = rand() % DELKA;
		if (!(i % 10000000))
			printf(".");
	}
	printf("\n");
}

DWORD WINAPI vlakno4(LPVOID x)
{
	if (x == (LPVOID)0)
		napln_pole(0, DELKA / 4, POLE);
	else if (x == (LPVOID)1)
		napln_pole(DELKA / 4, (DELKA / 2), POLE);
	else if (x == (LPVOID)2)
		napln_pole((DELKA / 2), (DELKA * 3) / 4, POLE);
	else
		napln_pole((DELKA * 3) / 4, DELKA, POLE);
	return 0;
}

DWORD WINAPI vlakno2(LPVOID x)
{
	if (x == (LPVOID)0)
		bubble_sort(0, DELKA / 2, POLE1);
	else if (x == (LPVOID)1)
		bubble_sort(0, DELKA - (DELKA / 2), POLE2);
	return 0;
}

// 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);
}

void splitArrays(int *l, int *r, int *pole) {
	
	for (int i = 0; i < DELKA / 2; i++) {
		l[i] = pole[i];
	}
	int pom = 0;
	for (int i = DELKA / 2; i < DELKA; i++) {
		r[pom++] = pole[i];
	}
}

void mergeArrays(int *l, int *r, int *pole, int sizel, int sizer) {
		
	int lx = 0, rx = 0, px = 0;
	while (px < DELKA) {
		if (lx >= sizel || rx >= sizer)
			break;
		if (l[lx] < r[rx]) {
			pole[px++] = l[lx++];
		} else if (l[lx] > r[rx]) {
			pole[px++] = r[rx++];
		} else {
			pole[px++] = l[lx++];
			pole[px++] = r[rx++];
		}
	}
	while (lx < sizel)
		pole[px++] = l[lx++];
	while (rx < sizer)
		pole[px++] = r[rx++];
}

int main(int na, char **arg)
{
	/*if (na != 2)
	{
		printf("Zadej pocet prvku, minimalne 1000000\n");
		system("PAUSE");
		return 0;
	}*/
	DELKA = atoi(arg[1]);
	/*if (DELKA < 1000000)
	{
	printf("Pocet prvku musi byt minimalne 1000000\n");
	system("PAUSE");
	return 0;
	}*/
	POLE = new TYP[DELKA];
	if (!POLE)
	{
		printf("Nelze alokovat pamet!\n");
		return 1;
	}
	srand((int)time(NULL));



	//Generovani nahodnych cisel do pole
	FILETIME cas_pred, cas_po;
	printf("Generuji nahodna cisla\n");

	GetSystemTimeAsFileTime(&cas_pred);

	napln_pole(0, DELKA, POLE);
	vypis_pole(0, 25, POLE);

	GetSystemTimeAsFileTime(&cas_po);
	printf("Cas generovani bez vlaken %d [ms]\n", kolik_ms(&cas_pred, &cas_po));



	/*
	//Hledani nejvetsiho prvku 3 vlakny
	printf("\nHledani nejvetsiho prvku pomoci 3 vlaken...\n");
	HANDLE p1, p2, p3;

	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, MAX2, MAX3) );
	printf( "Cas hledani byl %d [ms]\n", kolik_ms( &cas_pred, &cas_po ) );
	*/
	


	/*
	//hledani nejvetsiho prvku pomoci 2 vlaken
	GetSystemTimeAsFileTime(&cas_pred);

	p1 = CreateThread(0, 0, vlaknoA2, 0, 0, 0);
	p2 = CreateThread(0, 0, vlaknoB2, 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));

	printf("Hledani nejvetsiho prvku pomoci 2\ 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 ) );
	*/


	
	/*
	//Bubble sort bez vlaken
	GetSystemTimeAsFileTime(&cas_pred);

	bubble_sort(0, DELKA, POLE);

	GetSystemTimeAsFileTime(&cas_po);
	vypis_pole(0, 50, POLE);
	printf("Cas trideni byl %d [ms]\n", kolik_ms(&cas_pred, &cas_po));
	*/


	
	/*
	//Generovani pomoci 4 vlaken
	HANDLE p1, p2, p3, p4;

	GetSystemTimeAsFileTime(&cas_pred);

	p1 = CreateThread(0, 0, vlakno4, (LPVOID)0, 0, 0);
	p2 = CreateThread(0, 0, vlakno4, (LPVOID)1, 0, 0);
	p3 = CreateThread(0, 0, vlakno4, (LPVOID)2, 0, 0);
	p4 = CreateThread(0, 0, vlakno4, (LPVOID)3, 0, 0);

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

	GetSystemTimeAsFileTime(&cas_po);
	vypis_pole(0, 25, POLE);
	printf("Cas generovani s 4 vlakny %d [ms]\n", kolik_ms(&cas_pred, &cas_po));
	*/



	/*
	//Bubble sort pomoci dvou vlaken
	HANDLE p1, p2;

	POLE1 = new TYP[DELKA / 2];
	POLE2 = new TYP[DELKA - DELKA / 2];

	GetSystemTimeAsFileTime(&cas_pred);

	splitArrays(POLE1, POLE2, POLE);
	p1 = CreateThread(0, 0, vlakno2, (LPVOID)0, 0, 0);
	p2 = CreateThread(0, 0, vlakno2, (LPVOID)1, 0, 0);

	WaitForSingleObject(p1, INFINITE);
	WaitForSingleObject(p2, INFINITE);
	mergeArrays(POLE1, POLE2, POLE, DELKA / 2, DELKA - DELKA / 2);

	GetSystemTimeAsFileTime(&cas_po);
	vypis_pole(0, 25, POLE);
	printf("Cas trideni byl %d [ms]\n", kolik_ms(&cas_pred, &cas_po));
	*/


	system("PAUSE");
}    

Posted Dec 2, 2015, 10:38 PM UTC

10
Loading comments…