Zum Inhalt springen

OpenMP: Probleme mit ll-Typen und "Illegal instruction (core dumped)"


Empfohlene Beiträge

Geschrieben (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 von Schlitzauge
Geschrieben

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

Geschrieben

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 :):)

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...