Seite 1 von 1

floating point exception

Verfasst: Mi Nov 28, 2012 1:54 pm
von ttmgot
Hi,

ich programmiere gerade in C ein Programm, das herausfinden soll, ob eine Zahl eine Primzahl ist oder nicht. Die entsprechende Funktion sieht so aus:

Code: Alles auswählen


int isprime(int p){

	omp_set_num_threads(4);
	int d;
	int ergebnis = 1;

	#pragma omp parallel
	{


		#pragma omp for schedule(static, 5)
		for(d=2; d < p; d=d+1){

			if(p % d ==0){
				ergebnis = 0;
			}
		}

	}
	return ergebnis;


}


Das Kompilieren funktioniert einwandfrei, aber beim ausführen kriege ich immer eine Fehlermeldung. Die meldung ist eine zahl (jedesmal eine andere) gefolgt von

floating point exception (core dumped) ./a.out
Beim googeln hab ich allerdings als möglichen Fehler nur gekriegt, das das Programm möglicherweise versucht durch 0 zu teilen, aber das macht es ja nicht.

Weiß vielleicht jemand rat?

Re: floating point exception

Verfasst: Mi Nov 28, 2012 4:19 pm
von nufan
Hallo :)

Kannst du feststellen in welcher Zeile der Fehler auftritt? Noch besser wäre ein möglichst kleines, aber kompilierbares Beispiel inklusive den Anweisungen zum Kompilieren.

Re: floating point exception

Verfasst: Do Nov 29, 2012 10:13 am
von cloidnerux
Hi:

Code: Alles auswählen

int isprime(int n)
{
	for(int d = 2; d < n; d++)
	{
		if((n % d) == 0) return 0;
	}
	return 1;
}
Dieser Code macht bei mir keine Probleme.
Was aber sein kann, ist dass dein rechter Prameter von Modulo 0 ist:

Code: Alles auswählen

x % 0 => Error
Prüfe bitte deinen Code auf sowas.
Warum verwendest du so viel Multithreading gedöns? Was erhoffst du dir davon?
Man kann den Algorithmus Mathematisch sehr viel schneller machen, ohne Threads und so.

Re: floating point exception

Verfasst: Fr Nov 30, 2012 11:20 am
von ttmgot
erstmal sorry, das ich länger nicht geantwortet hab, mein Internet war down.

Scheint allerdings einfach so zu sein dass die Primzahl zu lang war, mit longs gehts (klassischer Anfängerfehler eben)

Warum verwendest du so viel Multithreading gedöns? Was erhoffst du dir davon?
Ich mach deswegen so viel parallel, weils eine Übungsaufgabe von der Uni ist, (ich fands auch ein bisschen blöd)

Re: floating point exception

Verfasst: Fr Nov 30, 2012 11:50 am
von Xin
ttmgot hat geschrieben:Scheint allerdings einfach so zu sein dass die Primzahl zu lang war, mit longs gehts (klassischer Anfängerfehler eben)
*lach* Ich programmiere seit über 25 Jahren, habe nur über den Quelltext geguckt und es auch nicht erkannt, bzw. auch nicht dran gedacht, dass es für einen solchen Quelltext eigentlich nach Überlauf schreit.
Von daher...
ttmgot hat geschrieben:Ich mach deswegen so viel parallel, weils eine Übungsaufgabe von der Uni ist, (ich fands auch ein bisschen blöd)
Magst Du OpenMP hier mal in einem Artikel vorstellen? So in der Form Installation, Compilereinstellung, ein, zwei Anwendungsbeispiele? Ich habe OpenMP auf der Todo-Liste für Proggen.org aber soweit unten, dass ich vermutlich erst in Jahren dazu komme. Vielleicht kannst Du da schon etwas vorgreifen, wenn Du Lust hast?

Re: floating point exception

Verfasst: Fr Nov 30, 2012 1:37 pm
von nufan
ttmgot hat geschrieben:Scheint allerdings einfach so zu sein dass die Primzahl zu lang war, mit longs gehts (klassischer Anfängerfehler eben)
Vielleicht eine blöde Frage... aber wie kann dieser Code einen Überlauf verursachen?!

Re: floating point exception

Verfasst: Fr Nov 30, 2012 2:21 pm
von Xin
dani93 hat geschrieben:
ttmgot hat geschrieben:Scheint allerdings einfach so zu sein dass die Primzahl zu lang war, mit longs gehts (klassischer Anfängerfehler eben)
Vielleicht eine blöde Frage... aber wie kann dieser Code einen Überlauf verursachen?!
Narf... mit meiner Erinnerung an den Code und der Aussage von eben erschien mit das logisch... jetzt, wo ich den Code erneut angucke, finde ich die Frage gar nicht so blöd.

Wieso waren dann die Primzahlen zu groß? Und warum sollte eine %-Anweisung überhaupt eine Floating-Point-Exception werfen. (Tuts aber, habe ich gerade extra mal getestet)

Womit die Frage bleibt, wann kann d == 0 werden? Wenn p < 0 ist, startet die For-Schleife nie. Ist p > 2, läuft sie, aber endet, bevor d den Überlauf schafft... ist p=0 oder p=1, startet die Schleife nicht.

Kannst den Quellcode mal mit Aufruf so posten, wie er den Fehler geworfen hat!?

Re: floating point exception

Verfasst: Fr Nov 30, 2012 4:53 pm
von ttmgot
Xin hat geschrieben: Magst Du OpenMP hier mal in einem Artikel vorstellen? So in der Form Installation, Compilereinstellung, ein, zwei Anwendungsbeispiele? Ich habe OpenMP auf der Todo-Liste für Proggen.org aber soweit unten, dass ich vermutlich erst in Jahren dazu komme. Vielleicht kannst Du da schon etwas vorgreifen, wenn Du Lust hast?
Ich kanns mal um Weihnachten rum versuchen, wenn ich ein bisserl mehr Zeit hab, allerdings arbeite ich mich selbst erst in das Thema rein (und in normales C, hatte bisher nur Java), deswegen kann ich von der Qualität her nichts versprechen.
Xin hat geschrieben:
Wieso waren dann die Primzahlen zu groß? Und warum sollte eine %-Anweisung überhaupt eine Floating-Point-Exception werfen. (Tuts aber, habe ich gerade extra mal getestet)

Womit die Frage bleibt, wann kann d == 0 werden? Wenn p < 0 ist, startet die For-Schleife nie. Ist p > 2, läuft sie, aber endet, bevor d den Überlauf schafft... ist p=0 oder p=1, startet die Schleife nicht.

Kannst den Quellcode mal mit Aufruf so posten, wie er den Fehler geworfen hat!?
Sicher hier:

Code: Alles auswählen

#include <stdio.h>
#include <omp.h>
#include <time.h>
#include <unistd.h>
#include <math.h>


int isprime(int p){

	omp_set_num_threads(4);
	int d = 2;
	int ergebnis = 1;

	#pragma omp parallel
	{


		#pragma omp for schedule(static, 5)
		for(d=2; d < p; d=d+1){

			if((p % d) ==0){
				ergebnis = 0;
			}
		}

	}
	return ergebnis;


}

int main(){

time_t start, end;

time (&start);



if(isprime(2147483647)){
printf("%d ist eine Primzahl\n", 2147483647);
}else{
}

time(&end);


printf("Das programm dauerte %f Sekunden\n", difftime(end,start)); 


return 0;
}
Ich dachte eben meine Primzahl wäre einfach zu groß, und wenn ich longs nehme scheints zu klappen

Re: floating point exception

Verfasst: Sa Dez 01, 2012 2:56 pm
von nufan
Mir ist dieses Verhalten noch immer schleierhaft ^^
valgrind sagt aber explizit:
valgrind hat geschrieben:==28429== Process terminating with default action of signal 8 (SIGFPE)
==28429== Integer divide by zero at address 0x402C80A14
==28429== at 0x400985: isprime._omp_fn.0 (main.c:21)
Zeile 21 ist wie zu erwarten die Modulo-Berechnung.

Jetzt hab ich aber was anderes versucht:

Code: Alles auswählen

#pragma omp for schedule(dynamic)
for(d=2; d < p; d=d+1){
Funktioniert ebenfalls und das mit int als Datentyp. Diese Berechnung dauert bei mir 62 Sekunden.
Was bedeutet dieses static?
Wikipedia hat geschrieben: schedule(type, chunk): This is useful if the work sharing construct is a do-loop or for-loop. The iteration(s) in the work sharing construct are assigned to threads according to the scheduling method defined by this clause. The three types of scheduling are:

* static: Here, all the threads are allocated iterations before they execute the loop iterations. The iterations are divided among threads equally by default. However, specifying an integer for the parameter chunk will allocate chunk number of contiguous iterations to a particular thread.
* dynamic: Here, some of the iterations are allocated to a smaller number of threads. Once a particular thread finishes its allocated iteration, it returns to get another one from the iterations that are left. The parameter chunk defines the number of contiguous iterations that are allocated to a thread at a time.
* guided: A large chunk of contiguous iterations are allocated to each thread dynamically (as above). The chunk size decreases exponentially with each successive allocation to a minimum size specified in the parameter chunk
Was aber ebenfalls funktioniert ist folgendes:

Code: Alles auswählen

#pragma omp for schedule(static)
for(d=2; d < p; d=d+1){
Diese Berechnung braucht nur 3 Sekunden.
Ohne mich genauer mit OpenMP auszukennen, behaupte ich jetzt dein Parameter für schedule (5) ist falsch ^^

Re: floating point exception

Verfasst: Sa Dez 01, 2012 5:34 pm
von cloidnerux
Mal am Rande. Ich habe mir etwas Gedanken über die Optimierung gemacht und habe mal meinen Algorithmus gegen den hier gezeigten laufen lassen.
Code:

Code: Alles auswählen

#include <stdio.h>
#include <windows.h>
 
int isprime(int n)
{
	for(int d = 2; d < n; d++)
	{
		if((n % d) == 0) return 0;
	}
	return 1;
}

int isprime2(int n)
{
	if(!(n & 1)) return 0;
	for(int d = 3; d*d <= n; d += 2)
	{
		if((n % d) == 0) return 0;
	}
	return 1;
}

int main()
{
	int a=0, b=10;
	int c = a % b;
	double elapsed = 0, elapsed2 = 0;
	double total1 = 0, total2 = 0;
	LARGE_INTEGER start, end, frequency;
	int e1, e2;
	if(!QueryPerformanceFrequency(&frequency))
	{
		printf("Error with timer");
		return 0;
	}
	printf("Start\n");
	for(int i = 2147483547; i < 2147483647; i++)
	{
		start.QuadPart = 0;
		end.QuadPart = 0;
		QueryPerformanceCounter(&start);
		e1 = isprime(i);
		QueryPerformanceCounter(&end);
		elapsed = (double)(end.QuadPart  - start.QuadPart) / (double)(frequency.QuadPart);
		QueryPerformanceCounter(&start);
		e2 = isprime2(i);
		QueryPerformanceCounter(&end);
		elapsed2 = (double)(end.QuadPart  - start.QuadPart) / (double)(frequency.QuadPart);
		printf("%d: alg1: %f, alg2: %f, %d\n", i, elapsed, elapsed2, e1-e2);
		total1 += elapsed;
		total2 += elapsed2;
	}
	printf("Alg1: %f, Alg2: %f", total1/100, total2/100);
	return 0;
}
Output auf meinen System:

Code: Alles auswählen

Start
2147483547: alg1: 0.000001, alg2: 0.000001, 0
2147483548: alg1: 0.000001, alg2: 0.000001, 0
2147483549: alg1: 41.730378, alg2: 1.847140, 0
2147483550: alg1: 0.000001, alg2: 0.000001, 0
2147483551: alg1: 0.000599, alg2: 0.000297, 0
2147483552: alg1: 0.000001, alg2: 0.000001, 0
2147483553: alg1: 0.000001, alg2: 0.000001, 0
2147483554: alg1: 0.000001, alg2: 0.000001, 0
2147483555: alg1: 0.000001, alg2: 0.000001, 0
2147483556: alg1: 0.000001, alg2: 0.000001, 0
2147483557: alg1: 0.000072, alg2: 0.000030, 0
2147483558: alg1: 0.000001, alg2: 0.000001, 0
2147483559: alg1: 0.000002, alg2: 0.000002, 0
2147483560: alg1: 0.000001, alg2: 0.000001, 0
2147483561: alg1: 0.000004, alg2: 0.000002, 0
2147483562: alg1: 0.000001, alg2: 0.000001, 0
2147483563: alg1: 41.714660, alg2: 1.839688, 0
2147483564: alg1: 0.000001, alg2: 0.000001, 0
2147483565: alg1: 0.000001, alg2: 0.000001, 0
2147483566: alg1: 0.000001, alg2: 0.000001, 0
2147483567: alg1: 0.000221, alg2: 0.000107, 0
2147483568: alg1: 0.000001, alg2: 0.000001, 0
2147483569: alg1: 0.000001, alg2: 0.000001, 0
2147483570: alg1: 0.000001, alg2: 0.000002, 0
2147483571: alg1: 0.000001, alg2: 0.000009, 0
2147483572: alg1: 0.000001, alg2: 0.000001, 0
2147483573: alg1: 0.000001, alg2: 0.000001, 0
2147483574: alg1: 0.000001, alg2: 0.000001, 0
2147483575: alg1: 0.000001, alg2: 0.000001, 0
2147483576: alg1: 0.000001, alg2: 0.000001, 0
2147483577: alg1: 0.000001, alg2: 0.000001, 0
2147483578: alg1: 0.000001, alg2: 0.000001, 0
2147483579: alg1: 41.887388, alg2: 1.842863, 0
2147483580: alg1: 0.000001, alg2: 0.000001, 0
2147483581: alg1: 0.000003, alg2: 0.000002, 0
2147483582: alg1: 0.000001, alg2: 0.000001, 0
2147483583: alg1: 0.000001, alg2: 0.000001, 0
2147483584: alg1: 0.000001, alg2: 0.000001, 0
2147483585: alg1: 0.000001, alg2: 0.000001, 0
2147483586: alg1: 0.000001, alg2: 0.000001, 0
2147483587: alg1: 41.633890, alg2: 1.819885, 0
2147483588: alg1: 0.000001, alg2: 0.000001, 0
2147483589: alg1: 0.000001, alg2: 0.000001, 0
2147483590: alg1: 0.000001, alg2: 0.000001, 0
2147483591: alg1: 0.000001, alg2: 0.000001, 0
2147483592: alg1: 0.000001, alg2: 0.000001, 0
2147483593: alg1: 0.000002, alg2: 0.000001, 0
2147483594: alg1: 0.000001, alg2: 0.000001, 0
2147483595: alg1: 0.000001, alg2: 0.000001, 0
2147483596: alg1: 0.000002, alg2: 0.000002, 0
2147483597: alg1: 0.000001, alg2: 0.000001, 0
2147483598: alg1: 0.000001, alg2: 0.000001, 0
2147483599: alg1: 0.000032, alg2: 0.000016, 0
2147483600: alg1: 0.000001, alg2: 0.000001, 0
2147483601: alg1: 0.000001, alg2: 0.000001, 0
2147483602: alg1: 0.000001, alg2: 0.000001, 0
2147483603: alg1: 0.000023, alg2: 0.000012, 0
2147483604: alg1: 0.000001, alg2: 0.000001, 0
2147483605: alg1: 0.000001, alg2: 0.000001, 0
2147483606: alg1: 0.000001, alg2: 0.000001, 0
2147483607: alg1: 0.000001, alg2: 0.000001, 0
2147483608: alg1: 0.000001, alg2: 0.000001, 0
2147483609: alg1: 0.000002, alg2: 0.000001, 0
2147483610: alg1: 0.000001, alg2: 0.000001, 0
2147483611: alg1: 0.000001, alg2: 0.000001, 0
2147483612: alg1: 0.000001, alg2: 0.000001, 0
2147483613: alg1: 0.000001, alg2: 0.000001, 0
2147483614: alg1: 0.000003, alg2: 0.000001, 0
2147483615: alg1: 0.000001, alg2: 0.000001, 0
2147483616: alg1: 0.000001, alg2: 0.000001, 0
2147483617: alg1: 0.000147, alg2: 0.000063, 0
2147483618: alg1: 0.000001, alg2: 0.000001, 0
2147483619: alg1: 0.000001, alg2: 0.000001, 0
2147483620: alg1: 0.000001, alg2: 0.000001, 0
2147483621: alg1: 0.000294, alg2: 0.000137, 0
2147483622: alg1: 0.000001, alg2: 0.000001, 0
2147483623: alg1: 0.000002, alg2: 0.000001, 0
2147483624: alg1: 0.000001, alg2: 0.000001, 0
2147483625: alg1: 0.000001, alg2: 0.000001, 0
2147483626: alg1: 0.000002, alg2: 0.000001, 0
2147483627: alg1: 0.000002, alg2: 0.000001, 0
2147483628: alg1: 0.000001, alg2: 0.000001, 0
2147483629: alg1: 41.135518, alg2: 5.702943, 0
2147483630: alg1: 0.000001, alg2: 0.000001, 0
2147483631: alg1: 0.000001, alg2: 0.000001, 0
2147483632: alg1: 0.000001, alg2: 0.000001, 0
2147483633: alg1: 0.000109, alg2: 0.000055, 0
2147483634: alg1: 0.000001, alg2: 0.000001, 0
2147483635: alg1: 0.000001, alg2: 0.000001, 0
2147483636: alg1: 0.000001, alg2: 0.000001, 0
2147483637: alg1: 0.000001, alg2: 0.000001, 0
2147483638: alg1: 0.000001, alg2: 0.000001, 0
2147483639: alg1: 0.000001, alg2: 0.000001, 0
2147483640: alg1: 0.000001, alg2: 0.000001, 0
2147483641: alg1: 0.000051, alg2: 0.000026, 0
2147483642: alg1: 0.000001, alg2: 0.000001, 0
2147483643: alg1: 0.000001, alg2: 0.000001, 0
2147483644: alg1: 0.000001, alg2: 0.000001, 0
2147483645: alg1: 0.000001, alg2: 0.000001, 0
2147483646: alg1: 0.000001, alg2: 0.000001, 0
Alg1: 2.081035, Alg2: 0.130534