Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Kevni

Frischling

  • »Kevni« ist der Autor dieses Themas

Beiträge: 13

Beruf: Azubi Anwendungsentwickler

  • Private Nachricht senden

1

24.09.2012, 15:13

Multithreading in C++

Hallo,

ich versuche gerade ein kleines parallelisiertes Programm mit C++ zu schreiben.
Berechnet werden die Anzahl von "bösen" und "nicht-bösen" Zahlen aus einer Menge von 0 bis X (Stichwort: Böse 7).

Mit Java konnte ich das ganze soweit parallelisieren, dass ich die Berechnungsdauer dritteln konnte.
In C++ sinkt die Gesamtdauer durch die Parallelität leider garnicht, jedoch die Dauer pro Thread (logischerweise).

Angenommen ich nehme die Menge 0 bis 1 Mrd., dauert die Berechnung mit einem Thread ca 14 Sekunden. Bei zwei Threads dauert ein Thread jeweils 7 Sekunden jedoch werden mir die Ergebnisse erst nach 14 Sekunden angezeigt.

Mein Lösungsansatz ist folgender:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <Windows.h>
#include "BoeseX.h"

//Globale Ergebnisse
uint ergBoese = 0;
uint ergSauber = 0;
double dauer = 0;
uint laufendeThreads = 0;

//Thread-Methode
void starteBerechnung(uint start, uint ende, Ziffer boese) {
    ++laufendeThreads;

    BoeseX* berechnung = new BoeseX(start,ende, boese);
    berechnung->Berechne();

    ergBoese    += berechnung->getTrefferBoese();
    ergSauber   += berechnung->getTrefferSauber();
    dauer       += berechnung->getDauer();
    std::cout << dauer << std::endl;

    --laufendeThreads;
}

void ergebnisAusgeben() {
    while (laufendeThreads != 0) { Sleep(10); };

    //Ergebnis anzeigen
    std::cout << "Boese Zahlen: \t\t" << ergBoese << std::endl;
    std::cout << "Saubere Zahlen: \t" << ergSauber << std::endl;
    std::cout << "#################################" << std::endl;
    std::cout << "Benchmark: " << dauer << " Sekunden" << std::endl;
}

int main() {
    uint obergrenze;
    std::cout << "Obergrenze eingeben: " << std::endl;
    std::cin >> obergrenze;

    uint threads;
    std::cout << "Wieviele Threads verwenden: " << std::endl;
    std::cin >> threads;

    std::cout << "#################################" << std::endl;

    //Array der Threads
    std::vector<std::thread> t;

    uint start = 0;
    uint ende = obergrenze / threads;

    //Threads starten
    for (int i=0;i < threads; ++i) {
        t.push_back( 
            std::thread(starteBerechnung, start, ende * (i+1), SIEBEN) 
        );

        start += ende;
    }

    //Ausgabe-Thread starten
    std::thread ausgabe = std::thread(ergebnisAusgeben);
    ausgabe.join();

    return 0;
}


ergebnisAusgeben ist mein neuester Versuch, da ich zuvor alle Berechnungs-Threads durch .join() pausiert hatte. Diese Variante bringt aber auch nichts.

Danke im voraus!

lg
Kevni

Kevni

Frischling

  • »Kevni« ist der Autor dieses Themas

Beiträge: 13

Beruf: Azubi Anwendungsentwickler

  • Private Nachricht senden

2

24.09.2012, 15:44

Hrrr sorry Leute, hatte einen dummen Denkfehler die ganze Zeit...ich addiere die Gesamtdauer des Programms, logisch dass dann 2 Threads zu je 7 Sekunden genauso dauern wie einer mit 14 Sekunden :D

Sorry für diejenigen die gerade darüber schauen, aber falls ihr sonst etwas zu bemängeln habt wär ich nicht abgeneigt dies zu hören ;)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

24.09.2012, 16:07

1) Du hast da undefiniertes Verhalten, die Variablen laufendeThreads etc. werden von mehreren Threads gleichzeitig gelesen und geschrieben. Das geht so nicht, da musst du synchronisieren (Stichworte: Mutex/Critical Section, Atomic Operation). Du hast schon Glück, dass das Ding überhaupt ans Stehenbleiben denkt...
2) Join doch einfach erst alle Threads und gib dann die Ergebnisse aus anstatt dieses laufendeThreads Busy-wait!?
3) Wieso muss die Ausgabe eigentlich in einem eigenen Thread laufen?
4) Schau dir mal std::async an, damit ließe sich das alles vermutlich wesentlich einfacher und eleganter lösen...

Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von »dot« (24.09.2012, 16:29)


Werbeanzeige