Schlitzauge Geschrieben 28. September 2011 Geschrieben 28. September 2011 (bearbeitet) Hi COM, ich hab da gerade ein kleines Problem mit via OpenMP-parallelisierten Schleifen. Genauer gesagt, wollte ich mich gerade mit nested loops beschäftigen, aber schon bei ner normalen OpenMP-for-Schleife haperts irgendwo. Zunächst: ---------------------------------------------------------------------------- Folgende Infos: OS: Scientific Linux 6.1 x64 (up2date) Kompiler: g++ (GCC) 4.4.5 20110214 (Red Hat 4.4.5-6) +kompatibel zu/ab: OpenMP v3.0 Glibc - x86_x64 - v2.12-1.25.el6_1.3 OpenMP - x86_64: libgomp.x86_64 : GCC OpenMP v3.0 shared support library Kompilierungsaufruf (Release): g++ -std=c++0x -m64 -fopenmp -Wall -Wextra -pedantic -pedantic-errors -O3 -s source.cpp -o dest ---------------------------------------------------------------------------- Es geht darum, einfach die Gesamtsumme durch n Iterationen zu ermitteln (also 1+2+3+4+usw.). Hier der Code: #ifdef _OPENMP #include <omp.h> #endif #include <stdlib.h> #include <stdio.h> #include <iostream> using namespace std; int main(int argc, char *argv[]) { const int NumValues = 96; unsigned long long result = 0; int NumberOfIterations = 0; for(int i=1;i<=NumValues;i++) { result+=i; NumberOfIterations++; } printf("Array-Summe SERIELL: %llu\n",result); printf("Benötigte Iterationen: %i\n",NumberOfIterations); result = 0; NumberOfIterations = 0; #pragma omp parallel reduction(+: result, NumberOfIterations) { #pragma omp for for(int k=1;k<=NumValues;k++) { result+=k; NumberOfIterations++; } } printf("Array-Summe PARALLEL: %llui\n",result); printf("Benötigte Iterationen: %i\n",NumberOfIterations); result = 0; NumberOfIterations = 0; getchar(); return 0; } Kompiler-Output: NestedLoop2.cpp: In function ‘int main(int, char**)’: NestedLoop2.cpp:23: warning: ISO C++ does not support the ‘ll’ gnu_printf length modifier NestedLoop2.cpp:37: warning: ISO C++ does not support the ‘ll’ gnu_printf length modifier NestedLoop2.cpp: At global scope: NestedLoop2.cpp:11: warning: unused parameter ‘argc’ NestedLoop2.cpp:11: warning: unused parameter ‘argv’ Bis hierhin funktioniert noch alles. Ausgabe: Array-Summe SERIELL: 4656 Benötigte Iterationen: 96 Array-Summe PARALLEL: 4656 Benötigte Iterationen: 96 Sobald man aber für "NumValues", einen größeren Wert nimmt, z.B. 100, erfolgt auf einmal folgende Ausgabe: Array-Summe SERIELL: 5050 Benötigte Iterationen: 100 [B]Illegal instruction (core dumped)[/B] Es nützt auch nichts, wenn ich andere Datentypen für "result" verwende. Ursprünglich hatte ich normal "int" verwendet. Da gabs lediglich Kompiler-Warnungen, wegen ungenutzter main-Parameter und auch die Ausgabe funktionierte: Array-Summe SERIELL: 5050 Benötigte Iterationen: 100 Array-Summe PARALLEL: 5050 Benötigte Iterationen: 100 Doch bei "int" ist aber auch schon relativ bei wenigen Iterationen Schluss, z.B. 500 Iterationen: [Array-Summe SERIELL: 125250 Benötigte Iterationen: 500 Illegal instruction (core dumped) Ist ja irgendwie auch klar, da der Wertebereich von "int" (32-Bit) per default von -32768-32767 geht bzw. als "unsigned int" von 0-65535. Deshalb habe ich begonnen, für "result", Datentypen mit größeren Wertebereichen zu verwenden, z.B. "long int". Das erlaubt dann natürlich mehr, dennoch bin ich nicht zufrieden mit den kleinen Zahlen. Ich weiß, es gibt sowas wie BIGINTEGER, aber das möchte ich momentan nicht verwenden. Aber es gibt doch die neueren Datentypen, insb. bzgl. 64-Bit, z.B.: long long unsigned long long etc. Nur, wie Ihr oben sehen könnt, funktioniert der parallele Part nicht. Bzw. betrachtet die Variante mit "int" für "result". Bei 500 Iterationen kommts zu "Illegal instruction (core dumped)". Nur warum? Die Single-Prozess-Variante vorher funktioniert doch. Es kann also eigentlich nicht am Wertebereich eines Datentyps liegen?! Auch die Single-Prozess-Variante mit "int" für "result" funktionierte (anscheinend ist int wohl 64-Bit breit, immerhin lasse ich mit "-m64" auch als 64-Bit-App kompilieren). Es muss also etwas mit OpenMP zu tun haben. Ebenso geben mir diese Kompiler-Zeilen zu denken: NestedLoop2.cpp:23: warning: ISO C++ does not support the ‘ll’ gnu_printf length modifier NestedLoop2.cpp:37: warning: ISO C++ does not support the ‘ll’ gnu_printf length modifier Diese werden dann erzeugt, wenn man bei printf() sowas wie "%ll" oder "%llu" anwendet, so wie im Beispiel-Code oben, was aber irgendwie notwendig ist, da "result" als Datentyp schließlich "unsigned long long" besitzt. Wäre wirklich super, wenn mich hier mal jemand aufklären könnte, wo der Fehler liegt bzw. was beachtet werden muss und wie printf() bei ll-Typen anzuwenden ist. Besten Dank und Grüße Schlitzauge :):) Bearbeitet 28. September 2011 von Schlitzauge Zitieren
flashpixx Geschrieben 28. September 2011 Geschrieben 28. September 2011 Ich kann den Fehler leider nicht nachvollziehen: Dein Programm liefert bei mir auf OSX & Gentoo: Array-Summe SERIELL: 112507500 Benötigte Iterationen: 15000 Array-Summe PARALLEL: 112507500i Benötigte Iterationen: 15000 Zitieren
Schlitzauge Geschrieben 28. September 2011 Autor Geschrieben 28. September 2011 In der Tat. Habe den Fehler soweit eingrenzen können. Es wurde doch nicht wie oben beschrieben kompiliert. Kompiliere ich wie beschrieben, so: g++ -std=c++0x -m64 -fopenmp -Wall -Wextra -pedantic -pedantic-errors -O3 -s source.cpp -o dest Erhalte ich folgende Ausgabe, wenn ich das Programm dann ausführe: Array-Summe SERIELL: 112507500 Benötigte Iterationen: 15000 Array-Summe PARALLEL: 112507500 Benötigte Iterationen: 15000 Als die Fehler auftraten, wurde allerdings so kompiliert: g++ -std=c++0x -m64 -mmmx -msse -msse2 -msse3 -mssse3 -msse4 -msse4a -msse4.1 -msse4.2 -mavx -msse2avx -maes -mpclmul -mfma -mfma4 -mxop -mlwp -mabm -m3dnow -mmovbe -mpopcnt -mcld -mcmodel=large -mcrc32 -mcx16 -msahf -fopenmp -Wall -Wextra -pedantic -pedantic-errors -O3 -s source.cpp -o dest Das Ganze durchlief einen etwas aufwändigen cmake-Prozess, wodurch dieser Kompiler-Aufruf zustande kam. Das Problem dabei, ich kann den Aufruf derzeit so nicht abändern, da dieser bei anderen Projekten so zum Einsatz kommt, gebraucht wird und bisher funktioniert hat. Vlt. kann man damit leben, ein paar Parameter zu entfernen, aber nicht alle, da diese noch gebraucht werden. Kann mir jemand sagen, warum es beim Parallelteil zu einem "Fehler" kommt, wenn der längere, etwas kompliziertere Kompileraufruf zum Einsatz kommt? An welchen Parameter liegt es? Grüße Schlitzauge :) Zitieren
flashpixx Geschrieben 28. September 2011 Geschrieben 28. September 2011 Mach doch mal einen kleineren Test, um zu schauen welche Optionen sich nicht vertragen. Zitieren
Schlitzauge Geschrieben 28. September 2011 Autor Geschrieben 28. September 2011 Bleibt wohl nichts anderes übrig. Muss ich aber auf später verschieben. Ich werde dann das Ergebnis hier posten. Besten Dank und Grüße Schlitzauge :):) Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.