Created
October 24, 2012 14:58
-
-
Save tdpsk/3946564 to your computer and use it in GitHub Desktop.
Ermitteln von Primzahlen nach dem Sieb des Eratosthenes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "Primzahlen.h" | |
| // Lege ein globales Array an für die Daten. Dank moderner Rechner darf man | |
| // davon ausgehen, dass das Array mit den Werten 0 initialisiert wird | |
| // Es ist ausreichend, die Hälfte des Maximalwertes zu nehmen, da wir nur | |
| // die ungeraden Werte prüfen und in diesem Array ablegen, ob sie Primzahlen | |
| // sind oder nicht | |
| unsigned char ppz[SIZE + 1]; | |
| HANDLE hThreads[ANZ_THREADS]; | |
| int main(void) | |
| { | |
| printf("Berechnen der Primzahlen bis %i\n\n", 2 * SIZE); | |
| double startzeit, endzeit, zwischenzeit, initzeit; // Zur Zeitmessung | |
| unsigned long counter; | |
| nimmzeit(&startzeit); | |
| // Anlegen der Threads zur Berechnung | |
| threads_anlegen(); | |
| nimmzeit(&initzeit); | |
| // Starten der Threads zur Berechnung | |
| threads_starten(); | |
| // Warte bis alle Threads fertig sind | |
| WaitForMultipleObjects(ANZ_THREADS, hThreads, TRUE, INFINITE); | |
| nimmzeit(&zwischenzeit); | |
| // Zaehlen der Primzahlen | |
| counter = zaehlen(); | |
| nimmzeit(&endzeit); | |
| // AUSGABE | |
| printf("Vergangene Zeit: %5.4f s\n", endzeit - startzeit); | |
| printf("-> Einrichten : %5.4f s\n", initzeit - startzeit); | |
| printf("-> Berechnung : %5.4f s\n", zwischenzeit - initzeit); | |
| printf("-> Zaehlen : %5.4f s\n", endzeit - zwischenzeit); | |
| printf("-------------------------\n"); | |
| printf("Anzahl : %i\n\n", counter); | |
| // ENDE AUSGABE | |
| system("pause"); | |
| } | |
| /** | |
| * Gibt einen aktuellen Timestamp zurück um die Dauer messen zu können | |
| */ | |
| void nimmzeit(double* messwert) | |
| { | |
| struct tm* zeit; | |
| struct timeb tb; | |
| ftime(&tb); | |
| zeit = localtime(&tb.time); | |
| *messwert = zeit->tm_hour * 3600.0 + zeit->tm_min * 60.0 + zeit->tm_sec + (double)tb.millitm/1000.0; | |
| } | |
| /** | |
| * Berechnung der Primzahlen | |
| */ | |
| static void berechnen(void *arg) | |
| { | |
| unsigned long index, index2; // Die beiden Indizes werden zum Durch- | |
| // laufen des Arrays benötigt | |
| char startwert = ((int)arg % ANZ_THREADS) + 1; | |
| // Es ist ausreichend, bis Wurzel(Array-Größe) zu zählen, da alles darüber | |
| // automatisch ein Vielfaches einer Zahl darunter ist | |
| for (index = startwert; index <= SQRT; index+=ANZ_THREADS) | |
| { | |
| if (ppz[index] == PRIM) | |
| { | |
| // Hier muss aus dem Index der tatsächliche Wert errechnet werden, | |
| // da unser Array ja nur den Primzahl-Zustand ungerader Zahlen | |
| // beinhaltet. | |
| // ** Echter Wert = Index * 2 + 1 | |
| for (index2 = 2*index*(index + 1); index2 <= SIZE; index2 += 2*index+1) | |
| { | |
| if (ppz[index2] == PRIM) // Selbst im RAM ist Schreiben teuer | |
| { | |
| ppz[index2] = NOPRIM; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Zaehlen der Primzahlen | |
| */ | |
| unsigned long zaehlen() | |
| { | |
| unsigned long globcounter = 0, index = 0; | |
| for (index = 0; index <= SIZE; index++) | |
| { | |
| if (ppz[index] == PRIM) | |
| { | |
| globcounter++; | |
| } | |
| } | |
| return globcounter; | |
| } | |
| /** | |
| * Threads für die Berechnung anlegen | |
| */ | |
| static void threads_anlegen() | |
| { | |
| SECURITY_ATTRIBUTES sa = | |
| { | |
| sizeof(SECURITY_ATTRIBUTES), | |
| 0, | |
| TRUE, | |
| }; | |
| char i; | |
| for (i = 0; i < ANZ_THREADS; i++) | |
| { | |
| DWORD threadId; | |
| hThreads[i] = (HANDLE)CreateThread( | |
| &sa, /* Thread security */ | |
| 4096, /* Thread stack size */ | |
| (LPTHREAD_START_ROUTINE)berechnen, /* Thread starting address */ | |
| (void *)i, /* Thread start argument */ | |
| CREATE_SUSPENDED, /* Create in suspended state */ | |
| &threadId); /* Thread ID */ | |
| if (hThreads[i] == INVALID_HANDLE_VALUE) | |
| { | |
| printf("Threads konnten nicht erstellt werden!\n\n"); | |
| system("pause"); | |
| } | |
| } | |
| } | |
| /** | |
| * Starten der Threads | |
| */ | |
| static void threads_starten() | |
| { | |
| char i; | |
| for (i = 0; i < ANZ_THREADS; i++) | |
| { | |
| ResumeThread(hThreads[i]); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <time.h> | |
| #include <sys/timeb.h> | |
| #include <process.h> | |
| #include <windows.h> | |
| #define PRIM 0 // 0 = es handelt sich um eine Primzahl | |
| #define NOPRIM 1 // 1 = es handelt sich nicht um eine Primzahl | |
| #define SIZE 50000000 // Die Größe des Arrays (= 0.5 * Größte Zahl) | |
| #define SQRT 7070 // Die Wurzel aus SIZE, bis zu der das Array iteriert | |
| // werden muss | |
| #define ANZ_THREADS 4 // Anzahl Threads | |
| void nimmzeit(double* messwert); | |
| static void berechnen(void *arg); | |
| unsigned long zaehlen(); | |
| static void threads_anlegen(); | |
| static void threads_starten(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment