Skip to content

Instantly share code, notes, and snippets.

@tdpsk
Created October 24, 2012 14:58
Show Gist options
  • Select an option

  • Save tdpsk/3946564 to your computer and use it in GitHub Desktop.

Select an option

Save tdpsk/3946564 to your computer and use it in GitHub Desktop.
Ermitteln von Primzahlen nach dem Sieb des Eratosthenes
#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]);
}
}
#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