Prozessaufteilung. was wie optimal Nutzen



  • hi,
    ich bin gerade an einem Projekt wo ich nicht weiter komme. Ich studiere Medieninformatik, doch zu diesem Thema habe ich leider noch keine Erfahrungen sammeln können und hoffe auf Eure fachlichen Kompetenzen.

    Folgendes Problem:
    Ich habe ein Programm mit mehreren Funktionen welches ich mit 2 verschiedenen Prozessen, mit einer gemeinsamen Liste(einfach verkettet), abarbeiten möchte.

    Zielstellung:
    Da 1 Prozess mit einer Reihe an Funktionen sequenziell etwas lange dauert, habe ich mit überlegt die Prozesse aufzuteilen. Dazu nutze ich eine einfach verkettet Liste die von beiden Seiten bearbeitet wird.

    -> ein grob zusammen gefasstes Beispiel:

    struct daten{
          float Wert;
    }
    
    struct element{
          struct daten    *info;
          struct element  *next;
    }
    
    void funktion_1(struct element *e)
    {
       // schreibt ans ende der Liste
    }
    
    void funktion_2(struct element *e)
    {
       // bekommt den Anker und liest das darauffolgende Element vom Anker
       // und löscht es danach
    }
    
    int main(){
    
        struct element meineListe,*x;
        struct element anker = {0,0};
    
       // hier soll jetzt die Prozessaufteilung stattfinden
    
        prozess_1(funktion_1(&meineDaten,anker,x));
        prozess_2(funktion_2(&meineDaten,anker,x));
    
        return 0;
    }
    

    so in etwas soll das aussehen.

    mit fork habe ich mich schon probiert doch leider erkennt dieser nicht die gemeinsame liste nach dem ich diese der Funktion übergeben habe.
    ich lese mich gerade in OpenMP ein und habe schon etwas rum probiert, leider weis ich nicht genug darüber um das zum laufen zu bekommen.

    Vielleicht habt ihr andere Ideen wie ich diese Parlellität mit einer gemeinsamen Liste hinbekomme. Vielleicht sehe ich auch nur den Wald vor lauter bäumen nicht.

    es gibt da ja noch pthread und andere schöne Sachen. nur geht es bei mir auch um optimale Abarbeitung mit Datensicherheit. Wenig CPU-Verbrauch wäre wünschenswert.

    Danke schon mal für eure Mühe.



  • freaksdd schrieb:

    struct daten{
          float Wert;
    }
    
    struct element{
          struct daten    *info;
          struct element  *next;
    }
    
    void funktion_1(struct element *e)
    {
       // schreibt ans ende der Liste
    }
    
    void funktion_2(struct element *e)
    {
       // bekommt den Anker und liest das darauffolgende Element vom Anker
       // und löscht es danach
    }
    
    int main(){
    
        struct element meineListe,*x;
        struct element anker = {0,0};
    
       // hier soll jetzt die Prozessaufteilung stattfinden
    
        prozess_1(funktion_1(&meineDaten,anker,x));
        prozess_2(funktion_2(&meineDaten,anker,x));
    
        return 0;
    }
    

    Das sieht verdächtig nach C aus. Bist du überhaupt im richtigen Forum?
    Wenn ja: warum benutzt du nicht std::list?

    mit fork habe ich mich schon probiert doch leider erkennt dieser nicht die gemeinsame liste nach dem ich diese der Funktion übergeben habe.

    Zwei Prozesse arbeiten selbstverständlich nicht im gleichen Speicherbereich. Was einer ändert sieht der andere nicht. Das ist der Sinn der Übung!

    ...
    nur geht es bei mir auch um optimale Abarbeitung mit Datensicherheit.

    Was soll das bedeuten?

    Wie die Verarbeitung aufgeteilt werden kann hängt davon ab, was deine Funktionen konkret machen. Gleichzeitig mit zwei Threads genau dieselben Daten zu manipulieren ist wenig sinnvoll, da das Synchronisieren der Threads schlussendlich langsamer sein kann, als alles nacheinander zu verarbeiten.

    C++11 bietet verschiedene Möglichkeiten, um mehrere Prozessoren zu benutzen. Pthreads sollte man da nicht mehr direkt benutzen.



  • Hey
    Danke erstmal für deine schnelle Antwort.
    das ist auch erstmal c mit der liste. mit dem std::list komm ich noch nicht so ganz klar ... das thema haben wir etwas überflogen, aber so geht es auch, da hast du recht.

    mit der Optimalität und Datensicherheit ist es so gedacht. das der eine Prozess an das eine Ende die Daten anhängt und der andere Prozess die Daten vom Anfang der Kette liest und nach dem lesen/verarbeiten löscht. natürlich wird das geprüft so das die beiden Prozesse nicht auf das selbe Element zugreifen.

    Mein Prof hat mir die Liste vorgeschlagen weil dieses ein relativ optimaler weg ist um die Zugriffszeiten möglichst gering zu halten.

    Das ist halt meine Frage. was ist schnelle und was langsamer? Ich muss von einem analog-wandler die Daten in weniger wie eine millisekunde auslesen und möglichst schnell über W-Lan versenden so das es einem Echtzeitsystem ähnelt.
    Da ich die Daten kontinuierlich von dem Wandler lese darf dort kein Zeitverzug statt finden. zusätzlich muss ich die daten per W-Lan senden wo auch fehlerbehandlung statt finden muss.

    Ich werde auch die sequenzielle abarbeitung eines Prozesses messen. es wäre aber auch interessant wie schnell das mit 2 Prozessen funktioniert. und da ich leider noch nicht so viel erfahrung damit sammeln konnte wollte ich hier mal nachfragen, nach anregungen suchen und vielleicht hat ja jemand eine zündene Idee wie ich das möglichst optimal löse.

    Danke noch mal für deine Antwort



  • Das Ganze funktioniert nur dann, wenn das Versenden per WLAN durchschnittlich schneller ist als das Lesen der Daten. Dabei wird die reine Prozessorgeschwindigkeit eher nie ausgenutzt. Problematisch ist es nur, wenn das Senden per WLAN mal blockiert und dann nicht gelesen werden kann.

    Mir fallen hier zwei Möglichkeiten ein:

    1. zwei Prozesse: du startest einen Sendeprozess, der mit dem Leseprozess per Pipe verbunden ist. Der Leseprozess schreibt die Daten direkt in die Pipe. Die Pipe dient dann als Puffer.

    2. zwei Threads (lesen und senden) und eine per Mutex gesicherte "Liste" (std::queue?)



  • okay ... ich weis nicht ob ich da falsch erklärt habe bzw sehe ich das mit dem Wlan nicht so tragich, da diese Liste immer länger wird, und kein Speicherzugriffsfehler erscheinen kann. es seid denn der speicher ist voll.

    Die idee mit der Pipe hatte ich auch schon. Ich bekomme von dem Wandler 4 float werte. da muss ich mich noch mal genau nachlesen ob man ein array als pipe nutzen kann.

    Dein zweiter Vorschlag mit den Threads ist ja im Prinzip das was ich gerne machen würde. jetzt gibt es ja aber verschiedene Varianten und verschiedene Arten von threads. mit pthreads habe ich einen zu hohen CPU-Verlust was ich z.B mit openMP nicht habe, da die Prozess-Aufteilung vom Betriebssystem übernommen wird.
    Ich würde gerne die zweite Idee mitnehmen und das aber in openMP lösen. Oder gibt es noch andere gleichwertigere nutzbare Prozessaufteilungen?

    das was du sicherlich meinst is so in dieser Art denk ich:

    /* beispiel2b.c */
    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    
    pthread_mutex_t mutex;
    char ch;
    
    void *print_stern (void *dummy)
    {
      pthread_mutex_lock (&mutex);
      ch = '*';
      sleep (1);
      printf ("%c\n", ch);
      pthread_mutex_unlock (&mutex);
      return NULL;
    }
    
    void *print_minus (void *dummy)
    {
      pthread_mutex_lock (&mutex);
      ch = '-';
      sleep (1);
      printf ("%c\n", ch);
      pthread_mutex_unlock (&mutex);
      return NULL;
    }
    
    int main ()
    {
      pthread_t p1, p2;
    
      pthread_mutex_init (&mutex, NULL);
    
      pthread_create (&p1, NULL, print_minus, NULL);
      pthread_create (&p2, NULL, print_stern, NULL);
    
      pthread_join (p1, NULL);
      pthread_join (p2, NULL);
    
      return 0;
    }
    

    Quelle: http://www.ijon.de/comp/tutorials/threads/synchro.html



  • Mal ganz langsam.

    Auf welchem Kenntnisstand bist du denn eigentlich?
    Ich hab den Eindruck, dass du zwar viele Fachbegriffe kennst, aber den großen Zusammenhang nicht. (Verbessere mich bitte!)

    Dass du unbedingt mit Threads (auch noch "irgendwelchen" Threads) dein Problem lösen willst, klingt für mich nach dem XY-Problem.

    Und mal so eben reingeworfen, in einer Millisekunde kann verdammt viel passieren 😉



  • Kenntnisstand:
    Ich studiere Medieninformatik. "gelernt" habe ich die sprachen C,C++,C#,Java,Shell,PHP, ...

    also ich weis "bisschen" was über die Sprachen und was es so gibt. doch im studium habe ich auch nicht alle themengebiete von a bis z gelernt. da gehört noch ne ordentliche portion selbststudium dazu was ich gerade betreibe.

    das was ich meine mit dem "irgendwie" ist dahin bezogen das es viele wege nach rom gibt. da ich im labor arbeite und verschiedene Sachen teste ... mach ich so oder so eine laufzeitanalyse und so weiter.

    mir geht es hier darum verschiedene Möglichkeiten aufgezeigt zu bekommen wie ich "nach Rom komme".

    du hast recht das ich den zusammenhang zwar kenne, aber nicht verstehe.
    Ich bin noch im Lern-Prozess 🙂



  • freaksdd schrieb:

    okay ... ich weis nicht ob ich da falsch erklärt habe bzw sehe ich das mit dem Wlan nicht so tragich, da diese Liste immer länger wird, und kein Speicherzugriffsfehler erscheinen kann. es seid denn der speicher ist voll.

    Wenn man unter der Dusche steht und es läuft oben mehr Wasser rein als unten raus, muss man rechtzeitig aufhören. Besser wäre es, wenn das Wasser schneller abläuft.

    Die idee mit der Pipe hatte ich auch schon. Ich bekomme von dem Wandler 4 float werte. da muss ich mich noch mal genau nachlesen ob man ein array als pipe nutzen kann.

    Nein!

    Dein zweiter Vorschlag mit den Threads ist ja im Prinzip das was ich gerne machen würde. jetzt gibt es ja aber verschiedene Varianten und verschiedene Arten von threads. mit pthreads habe ich einen zu hohen CPU-Verlust

    Das ist Blödsinn! Wenn du "CPU-Verlust" hast, lässt du den Thread ohne sinnvolle Arbeit rumorgeln. Im Zweifelsfall benötigst du eine Conditionvariable.

    Benutze C++11 Threads statt pthreads!

    was ich z.B mit openMP nicht habe, da die Prozess-Aufteilung vom Betriebssystem übernommen wird.

    Ich kenne OpenMP nicht wirklich, bezweifle aber, das ds für diesen Zweck geeignet ist.

    Ich würde gerne die zweite Idee mitnehmen und das aber in openMP lösen. Oder gibt es noch andere gleichwertigere nutzbare Prozessaufteilungen?

    das was du sicherlich meinst is so in dieser Art denk ich:

    /* beispiel2b.c */
    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    
    pthread_mutex_t mutex;
    char ch;
    
    void *print_stern (void *dummy)
    {
      pthread_mutex_lock (&mutex);
      ch = '*';
      sleep (1);
      printf ("%c\n", ch);
      pthread_mutex_unlock (&mutex);
      return NULL;
    }
    
    void *print_minus (void *dummy)
    {
      pthread_mutex_lock (&mutex);
      ch = '-';
      sleep (1);
      printf ("%c\n", ch);
      pthread_mutex_unlock (&mutex);
      return NULL;
    }
    
    int main ()
    {
      pthread_t p1, p2;
    
      pthread_mutex_init (&mutex, NULL);
    
      pthread_create (&p1, NULL, print_minus, NULL);
      pthread_create (&p2, NULL, print_stern, NULL);
    
      pthread_join (p1, NULL);
      pthread_join (p2, NULL);
    
      return 0;
    }
    

    Quelle: http://www.ijon.de/comp/tutorials/threads/synchro.html

    Das Ist doch nicht mehr als Hello World für Threads.



  • freaksdd schrieb:

    mit pthreads habe ich einen zu hohen CPU-Verlust

    Nö, hast du nicht, pthreads vernichtet keine CPUs.
    OK, Scherz beiseite, ... hast du trotzdem nicht. Wie kommst du auf die Idee dass PTHREADS so viel Overhead hätte?

    Wobei ich eher die Standard C++ Threads empfehlen würde. Weil du dich mit PTHREADS unter Windows z.B. schön brausen gehen kannst. (Ja, ich weiss es gibt auch Implementierungen für Windows, aber die würde ich nicht verwenden wollen.)

    freaksdd schrieb:

    was ich z.B mit openMP nicht habe, da die Prozess-Aufteilung vom Betriebssystem übernommen wird.

    Auch falsch.
    OpenMP bringt ne eigene Runtime mit, das OS weiss nix von OpenMP. Ob jetzt PTHREADS Library oder OpenMP Runtime - wo soll der Unterschied sein?


  • Mod

    Noch genauer: Alles was in POSIX irgendwie mehrere Threads benutzt, benutzt unter der Haube letztlich pthreads. OpenMP, C++11, egal wer. Denn das sind die Threads, die das OS bereit stellt, es gibt keine anderen. Das gilt gleichermaßen für alle anderen Systeme. Niemand (auch OpenMP) implementiert seine eigenen Threads. Wie sollte das auch gehen? Interprozesskommunikation? Das ist doch wahnsinnig umständlich verglichen mit den Threadmechanismen, die das OS direkt bereit stellt und ist selber auch nur ein weiterer OS-Mechanismus (eben eine Ebene höher).



  • okay ... ich habe soweit erstmal verstanden.
    das mit den cpu-Verlust hab ich nur gelesen und wird nicht empfohlen da egal welcher thread es immer zu mehr cpu-last kommt als wenn man keine hat. da stand was von 2-15 % mehr last.

    mit dem Thema Threads habe ich mich hier wahrscheinlich biss lächerlich gemacht weil ich das nicht wirklich kenne und nur nachgelesen habe.
    Es ist aber schön zu wissen das es euch gibt die mehr ahnung davon haben und dafür bedanke ich mich sehr.

    Ich werde es jetzt so machen:
    Ich probiere es ohne threads + mit threads(verschiedene arten)

    da ich bei den threads nun wirklich keine ahnung habe würde ich gerne wissen welche arten ich in c++ probieren kann?
    Ich werde alle testen und die laufzeit messen. Und das Programm was am schnellsten und zuverlässigsten läuft werde ich dann wahrscheinlich auch verwenden.


  • Mod

    freaksdd schrieb:

    da ich bei den threads nun wirklich keine ahnung habe würde ich gerne wissen welche arten ich in c++ probieren kann?

    Willst du wirklich eine komplette Liste? Die ist entweder sehr kurz (reines Standard-C++ kennt nur seine eigenen Threads) oder sehr lang (es gibt unzählige Threadingbibliotheken). Letzteres ist auch irgendwie sinnlos. Eine abstrakte Schnittstelle wie OpenMP ist für ganz andere Szenarien optimiert als eine low-level Schnittstelle wie die rohen pthreads. Die Wahl sollte daher nicht erfolgen, indem du verschiedene, von dir geschriebene Programme vergleichst, sondern indem du dir vorher überlegst, was für deinen Anwendungsfall die optimale Wahl wäre. Brauchst du Feinkontrolle? Dann ist eher eine low-level Schnittstelle gefragt. Zählt eher einfaches Entwickeln? Dann ist eine höhere Abstraktionsstufe besser.

    Ich werde alle testen und die laufzeit messen.

    Wenn du es wirklich bis zum Gipfel treibst, dann wird immer die low-leveligste Schnittstelle gewinnen, weil du mit der Sachen machen kannst, die mit höherstufigen Schnittstellen nicht gehen. Aber dafür entwickelst du halt 2 Tage statt 2 Stunden am gleichen Programm. Wie willst du das vernünftig vergleichen?

    Und das Programm was am [...] zuverlässigsten läuft [...]

    Am zuverlässigsten? Ein Programm ist entweder richtig oder eben nicht. Da gibt es keine Abstufungen. Wenn es einen einzigen Fall gibt, wo es nicht richtig läuft, dann ist das Programm falsch. Ich hoffe, du benutzt nur richtige Programme und du programmierst so, dass deine Programme möglichst auf Anhieb richtig sind.
    Das gilt ganz besonders bei parallelen Programmen, bei dem gewisse Fehler nichtdeterministisch auftreten können. Wenn dein Programm abundzu einen Deadlock hat und abundzu nicht, dann ist es falsch, selbst wenn es in 90% der Fälle keinen Deadlock hat. Basta!



  • hi,
    mir würde ni kleine übersicht der c-Bibliotheken reichen. möglichst nicht viel andere Bibliotheken.
    Ich würde schon gerne die standarts nutzen wollen von threads mit denen man halt gute erfahrungen gemacht hat bzw man sich sicher ist das die zuverlässig ihre funktion erfüllen ohne großes hin und her.

    wichtig dabei ist das die beiden threads auf den selben speicher zugreifen und es da eine einfach funktion gibt um konflikte zu vermeiden zb "lock" oder sowas.
    nun habe ich schon mal mit lock gearbeitet oder ähnlichem. wie ist das bei einer vereinfachten kette. das müsste ja genau so funktionieren wenn man dien speicherbereich sperrt. das lesen aus der liste kann verzögert sein falls das schneller als das reinschreiben in die liste sein sollte. nur das schreiben sollte möglichst schnell und sicher erfolgen.
    PS: es gab nun andere kriterien vom Prof wo nur das schreiben in die Liste am schnellsten und zuverlässigsten sein muss. das lesen aus der kette kann verzögert sein.

    was könnt ihr mir dementsprechend anbieten? ich würde das jetzt erstmal klassisch über pthread machen.

    kann man statt 2 threads auch den hauptprozess und einen thread nehmen? bei pthread denk ich ist das so das beide threads beendet werden müssen bevor der "master-prozess" weiter macht. lieg ich da richtig oder falsch? bitte korrigiert mich.

    und immer wieder besten dank für eure tips und mühe 🙂


  • Mod

    freaksdd schrieb:

    hi,
    mir würde ni kleine übersicht der c-Bibliotheken reichen.

    Wieso denn jetzt auf einmal C, wenn du doch C++ machst? 😕

    wichtig dabei ist das die beiden threads auf den selben speicher zugreifen und es da eine einfach funktion gibt um konflikte zu vermeiden zb "lock" oder sowas.

    Das ist Grundfunktion, ohne die man Threads gar nicht nutzen könnte. Eine Threadbibliothek, die das nicht bietet, gibt es nicht auf der Welt.

    kann man statt 2 threads auch den hauptprozess und einen thread nehmen?

    Ja, selbstverständlich.



  • ich mein natürlich c++, sorry.

    ich bin gerade dabei mir die bibliothek von "boost" zu installieren. also boost::thread. is die zb empfehlenswert?



  • Moment: Willst Du oder musst Du eigentlich Threads verwenden?

    Mir kommt es etwas spanisch vor, dass Du mittlerweile boost installierst, aber von std::queue noch nix gehoert hast.

    Und dann (sorry, wenn das schon beantwortet wurde): Benutzt Du C++11?



  • das mit dem "muss" oder "kann" -verwenden is so ne sache. je nachdem was besser ist von der leistung her. ich muss es probieren was schneller und sicher ist.

    ich bin gerade mächtig bei google unterwegs um herauszufinden was es alles an thread bibliotheken gibt und probier die halt alle mal aus. momentan bin ich bei boost ... aber da habe ich noch probleme beim kompilieren.

    ich arbeite mit dem raspberry pi und debian.
    bei der versionsabfrage von g++ kommt bei mir "(debian 4.5.3- 14+rpil) 4.6.3
    ich schau gerade ob das die aktuellste ist die man auf debian nutzen kann.



  • freaksdd schrieb:

    das mit dem "muss" oder "kann" -verwenden is so ne sache. je nachdem was besser ist von der leistung her. ich muss es probieren was schneller und sicher ist.

    Gerald M. Weinberg schrieb:

    If it doesn't have to produce correct results,
    I can make it arbitrarily fast.

    🙂

    freaksdd schrieb:

    ich bin gerade mächtig bei google unterwegs um herauszufinden was es alles an thread bibliotheken gibt und probier die halt alle mal aus. momentan bin ich bei boost ... aber da habe ich noch probleme beim kompilieren.

    Du verschwendest Zeit.
    Mit dem 4.6.3 und im Jahre des Herrn 2014 wirst Du C++11 benutzen.
    Nimm dann auch die Threads aus der Standardbibliothek.
    Wenn überhaupt.
    Das ist jedenfalls meine bescheidene Meinung.

    Ist denn Dein Programm "Single Threaded" schon fertig und zu langsam?



  • ich hab schon mal geschaut wie man das mit dem c++11 übersetzt. würde theoretisch funktionieren.
    was kann ich mir unter der aktuellen version von c++ vorstellen? wird das schneller übersetzt oder gibt es nur zusätzliche Funktionen?

    jein ... das Programm ist noch in einzel stücke und muss noch zusammen gesetzt werden. im groben und ganzen ist es aber faaaast fertig


  • Mod

    freaksdd schrieb:

    was kann ich mir unter der aktuellen version von c++ vorstellen?

    http://en.wikipedia.org/wiki/C%2B%2B#Standardization

    wird das schneller übersetzt

    Nein, eher langsamer. Aber ich glaube, du hast eine völlig falsche Vorstellung, was du da gerade gefragt hast. Begriffe, die du momentan vermutlich nicht richtig einordnest:
    -Programmiersprache
    -Programm
    -Compiler
    -C++
    Mach dich mal schlau.

    Wenn du solche Wissenslücken hast, dann sind Threads noch ferne Zukunftsmusik für dich.

    oder gibt es nur zusätzliche Funktionen?

    Dies.


Anmelden zum Antworten