Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

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

Empfohlene Antworten

Veröffentlicht

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

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

  • Autor

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

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.