Kann man einem Thread eine CPU zuordnen??? Bsp. Primberechnung
-
Dieser Thread wurde von Moderator/in Phoemuex aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Im Buch "Windowsprogrammierung" von Charles Petzold gibt es ein Kapitel 20 "Multitasking und Multithreading", dort gibt es einen Unterpunkt "Seiteneffekte":
...
Es sieht so aus, als müsse der gleichzeitige Zugriff zweier Threads auf dasselbe Fenster durch einen kritischen Abschnitt verhindert werden. Experimente, die ich in diese Richtung angestellt habe, zeigen aber, dass Windows bei grafischen Zeichenfunktionen selbst für die Serialisierung sorgt: Zu jedem Zeitpunkt kann immer nur ein Thread in ein Fenster zeichnen. Ein Zweiter Thread, der da gleichzeitig versucht, bleibt so lange blockiert, bis der erste Thread seine Operationen abgeschlossen hat.Diese Aussage scheint zu erklären, warum die CPU Auslastung auf etwa die Hälfte beschränkt bleibt. Während der erste Thread zeichnet, wartet der zweite Thread und der entsprechende CPU Kern hat währenddessen nichts zu tun - die Auslastung sinkt.
Ich habe das Programm bei mir zum Laufen gebracht, um zu sehen, wie es funktioniert. Hier mein Makefile:all: mingw32-gcc main.c -o main.exe -mwindows
Ich beobachte im Prinzip dasselbe Verhalten wie rom4o. Wenn ich beide Threads aktiviere, sinkt bei meinem Centrino Duo 1.8 GHz die CPU Auslastung auf etwa 30 Prozent. Wahrscheinlich habe ich langsameren Rechner/Grafikkarte und die beiden Threads müssen entsprechend länger warten...
-
Hallo Leute, erstmal Danke für die vielen Antworten,
na ist ja auch ein aktuelles Thema.@unskilled
Also der folgende BefehlRectangle (hdc1 ,rand()%200 ,rand()%200 ,rand()%200, rand()%200);
funktioniert wunderbar in der Version 6 von MS Visual C++,
mit der arbeite ich nämlich. Ich weiss, die ist sehr alt schon 10Jahre
aber ich fahre bis jetzt noch ganz gut damit, will mir aber ein
aktuelles Visual Studio zulegen.Der Befehl funktioniert so
Rectangle (hdc1 ,rect.left ,rect.top ,rect.right, rect.bottom);
hdcl ist in meinem Fall das Zielobjekt, in das gezeichnet werden soll
und die einzelnen Einträge werden mit zufälligen Zahlen zwischen 1-200 belegt.
Dabei kann es auch sein, dass einige Rechtecke nicht gezeichnet werden, wenn
left>right oder top>bottom ist, aber bei der Zahl an Rechtecken die gezeichnet werden ist das nicht wichtig.@hustbaer
Hallo, ja ich weiss, dass ich nix synchronisiert habe, konnte das ja bis dato auch nicht. Aber ich befasse mich ja fortwährend mit dem Thema.
Und zu den Primzahlen später.@Phoemux, danke sehr fürs verschieben des Threads....
@abc.w
Sehr schön, dass es bei dir läuft und du es probiert hast.
Damit wäre ja dann meine Frage geklärt.Schade...aber ich arbeite nun an
meiner ursprünglichen Idee, das Programm zur Primzahlenberechnung.
Die Singlecore Variante habe ich fertig und läuft mit halber CPU-Auslastung wie gewohnt.In der Dualcore-Variante möchte ich das Problem 3teilen,
3 Threads, die ersten beiden prüfen wie schon gesagt die jeweils
übernächste ungerade Zahl und bei "true" sollen die Ergebnisse in eine Queue.
Aus dieser soll dann der dritte Thread lesen und die Ergebnisse zeichnen.Bis jetzt weiss ich noch nicht wie ich die Threads synchronisieren soll.
Ich möchte das wie in folgendem Beispiel haben:
...
35
37prim angenommen Thread1 rechnet noch
39 und Thread2 ist fertig aber soll auf Thread1 warten bis der mit 41 beginnt
Nun, fangen beide Threads mit jeweils 41 und 43 an
41prim angenommen Thread1 braucht länger dann soll
43prim Thread2 sein Ergebnis erst in die Queue schreiben wenn 41 drin steht
sonst ist die Reihenfolge falsch
45
47prim
49
...
Ich weiss, dass ich so nicht die 100%Auslastung erzielen werde aber auf jeden Fall mehr als 50%.
Die Frage ist, wie ich den Einen auf den anderen Thread warten lasse und umgekehrt?
Ich dachte mir vielleicht mit SetEvent() und einer "Wait Function" oder ähnlich.
Vielleicht hat ja einer von euch Ahnung davon?Vielen Dank,
bb rom4o ...
-
rom4o schrieb:
Bis jetzt weiss ich noch nicht wie ich die Threads synchronisieren soll.
Ich möchte das wie in folgendem Beispiel haben:
...
35
37prim angenommen Thread1 rechnet noch
39 und Thread2 ist fertig aber soll auf Thread1 warten bis der mit 41 beginnt
Nun, fangen beide Threads mit jeweils 41 und 43 an
41prim angenommen Thread1 braucht länger dann soll
43prim Thread2 sein Ergebnis erst in die Queue schreiben wenn 41 drin steht
sonst ist die Reihenfolge falsch
45
47prim
49
...mach doch einen problemerzeuger und einen lösungsempfänger. der erzeuger gibt die probleme der reihe nach raus. der empfämger nimmt sie auch ungeordnet an, aber sortiert sie vorm anzeigen, also der hält falsch eingereite lösungen einfach kurz zurück.
rom4o schrieb:
Ich weiss, dass ich so nicht die 100%Auslastung erzielen werde aber auf jeden Fall mehr als 50%.
sag das nicht. nehmen wir an, du checkst primzahlen im bereich um eine milliarde per triel division. da sind die primzahlen schon selten. ca jede zwanzigste ist prim. und bei primzahlen machste 15000 divisionen. viell viele zahlen haben aber kleine teiler. und die sind praktisch sofort fertig. von deinen 20 prozessoren würden die meiste zeit 19 leer warten auf den einen glücklichen, der ne primzahl getroffen hat.
deswegen sollen sich die anderen rugig beim problemversorger bedienen dürfen und schonmal vorauslaufen.
-
Hallo volkard,
Danke sehr für die rasche Antwort.
Stimmt das leuchtet ziehmlich ein. Was du da vorschlägst fordert natürlich
eine ganz neue Struktur meines Programms.
Abgesehen davon habe ich noch keine Ahnung, wie ich die Geschichte mit den Threads händeln werde.
Jedoch scheint mir dein Vorschlag sehr viel effektiver zu sein, als mein Ansatz.
Also werde ich, dem jeweils wartenden CPU-Kern die nächste Zahl zum berechnen geben? So habe ich dies verstanden. Dafür muss man ja ermitteln welcher Kern gerade frei ist, hmmhmmmmm "nächste Frage"?Für die, die es interessiert. Hier ist mein SingleCoreCode....nicht anspruchsvoll
aber leicht erweiterbar.// PrimSingleCore.cpp : Definiert den Einsprungpunkt für die Anwendung. // #include "stdafx.h" #include <windows.h> #include <stdlib.h> #include <math.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); HINSTANCE hInstGlobal; HWND hWindow, hButtonStart, hButtonStop, hButtonExit; HDC hdc; static RECT rect, rect1; SYSTEMTIME systime,systimeold; //time-variable int hDiff = 0; int mDiff = 0; int sDiff = 0; int msDiff = 0; CONST aim = 500000; //Zielzahl int count; //Anzahl char *Gstring; //globaler String bool th1runs; bool flag1; const UINT TimerSec = 1; //TIMER int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { hInstGlobal = hInstance; WNDCLASS WndClass; WndClass.style = 0; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.lpfnWndProc = WndProc; WndClass.hInstance = hInstance; WndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW+11); WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); WndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION); WndClass.lpszMenuName = 0; WndClass.lpszClassName = "WinProg"; RegisterClass(&WndClass); Gstring = new char[20]; SetTimer(hWindow, TimerSec, 14, NULL); //TIMER hWindow = CreateWindow("WinProg","PrimDualCore", WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, 0,0,800,600,NULL,NULL, hInstance, NULL); ShowWindow (hWindow, nCmdShow); UpdateWindow (hWindow); MSG Message; while (GetMessage(&Message, NULL, 0, 0)) { DispatchMessage(&Message); } return (Message.wParam); } void calcDiff() //Zeitschieber-Methode { hDiff = systime.wHour-systimeold.wHour; mDiff = systime.wMinute-systimeold.wMinute; sDiff = systime.wSecond-systimeold.wSecond; msDiff= systime.wMilliseconds-systimeold.wMilliseconds; if(msDiff<0){sDiff--; msDiff=msDiff+1000;} if(sDiff<0){mDiff--; sDiff=sDiff+60;} if(mDiff<0){hDiff--; mDiff=mDiff+60;} if(hDiff<0){hDiff=hDiff+24;} } bool Prim(int zahl) { bool devided = false; // erg = sqrt(aim); for(int k=3;k<(sqrt(zahl)+1);k=k+2) { if((zahl%k) == 0){ devided=true; k=zahl;} } return !devided; } DWORD WINAPI ThreadProc1( LPVOID pvoid ) { flag1 = false; InvalidateRect(hWindow, &rect1, TRUE); TEXTMETRIC tm; GetTextMetrics (hdc, &tm); int i; //Laufvariable int ix,iy; count=1; //wegen der 2 ix = 0; iy = 0; char *string; string = new char[20]; { // einmalige Ausgabe der 2 da diese nicht im DB von Prim(2) ist hdc = GetDC (hWindow); SetBkColor (hdc, RGB(236,233,216)); wsprintf(string,"%01d",2); TextOut (hdc, ix, iy, string, lstrlen(string)); iy = iy + tm.tmHeight; ReleaseDC (hWindow, hdc); } for (i=3;i<=aim;i=i+2) { if(Prim(i)) { count++; hdc = GetDC (hWindow); wsprintf(string,"%01d",i); SetBkColor (hdc, RGB(236,233,216)); TextOut (hdc, ix, iy, string, lstrlen(string)); iy = iy + tm.tmHeight; if ((iy/tm.tmHeight) == 33) { iy = 0; ix = ix + 90; } if(ix>770) { ix=0; iy=0;} ReleaseDC (hWindow, hdc); } } flag1 = true; GetSystemTime(&systime); //take time END calcDiff(); InvalidateRect(hWindow, &rect1, TRUE); delete [] string; th1runs = false; return NULL; } LRESULT CALLBACK WndProc (HWND hWnd, UINT uiMessage, WPARAM wParam,LPARAM lParam) { static HANDLE hThread1; switch(uiMessage) { case WM_SIZE: { rect.left = 0; //x-links TEST rect.top = 0; //y-oben TEST rect.right = 800; //x-rechts TEST rect.bottom = 600; //y-unten TEST rect1.left = 360; //x-links TEST rect1.top = 530; //y-oben TEST rect1.right = 800; //x-rechts TEST rect1.bottom = 600; //y-unten TEST return 0; } case WM_CREATE: hButtonStart = CreateWindow ("BUTTON","START", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10,540,100,20, hWnd,(HMENU) 1, hInstGlobal, NULL); hButtonStop = CreateWindow ("BUTTON","STOP", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 120,540,100,20, hWnd,(HMENU) 2, hInstGlobal, NULL); hButtonExit = CreateWindow("BUTTON","Exit", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 250,540,80,20, hWnd,(HMENU) 3, hInstGlobal, NULL); return 0; case WM_TIMER: { //InvalidateRect(hWnd, &rect1, TRUE); // bewirkt die Aktuallisierung im Bereich von rect1 //TIMER return 0; } case WM_PAINT: { HDC hdc; PAINTSTRUCT ps; char *WMstring; WMstring = new char[1]; WMstring[0] = 169; // das (C)reated hdc = BeginPaint (hWnd, &ps); //BEGIN PAINT SetBkColor (hdc, RGB(236,233,216)); SetTextColor (hdc, RGB(180,0,0)); TextOut (hdc, 360, 540, "time: ", lstrlen("time: ")); if(flag1) { wsprintf( Gstring , "%02d:%02d:%02d:%03d",hDiff,mDiff,sDiff,msDiff); TextOut (hdc, 400, 540, Gstring, lstrlen(Gstring)); } SetTextColor (hdc, RGB(0,180,0)); TextOut (hdc, 540, 540, "count: ", lstrlen("count: ")); if(flag1) { wsprintf( Gstring , "%01d",count); TextOut (hdc, 590, 540, Gstring, lstrlen(Gstring)); } SetTextColor (hdc, RGB(187,187,187)); SetBkColor (hdc, RGB(236,233,216)); //Rot=236 Grün=233 Blau=216 (standart Hellgrau) TextOut (hdc, 520+184,540, WMstring, 1); TextOut (hdc, 520+200,540, "by rom4o", 8); EndPaint (hWnd, &ps); //END PAINT delete WMstring; return 0; } case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { if ( (LOWORD(wParam) == 1) && (th1runs == false) ) { hdc = GetDC (GetParent((HWND) lParam)); InvalidateRect(hWnd, &rect, TRUE); DWORD dwThreadParam1 = 1; DWORD dwThreadID1; th1runs = true; GetSystemTime(&systimeold); //take time BEGIN hThread1 = CreateThread (NULL, 0, ThreadProc1, &dwThreadParam1, 0, &dwThreadID1); } if (LOWORD(wParam) == 2) { TerminateThread (hThread1, 0); th1runs = false; } if (LOWORD(wParam) == 3) { SendMessage (GetParent((HWND)lParam), WM_DESTROY ,0 ,0); } } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc (hWnd, uiMessage, wParam, lParam); }
Nun denn vielen Dank für den Tip, ich grüble weiter und gehen nun erstmal zu Bett.
grüße rom40
-
rom4o schrieb:
Also werde ich dem jeweils wartendem CPU-Kern die nächste Zahl zum berechnen geben? So habe ich dies verstanden. Dafür muss man ja ermitteln welcher Kern gerade frei ist,....haha nächste Frage.
ich denke etwa an sowas:
alle threads legen bei programmstart los.
jeder thread macht nur for(;;) { holeAufgabe(); rechne(); gibErgebnis(); }
holeAufgabe und gibErgebnis schützen sich einfach durch CreateMutex und ihre freunde.
das heißt, daß das erzeugen einer aufgabe nicht von einem bestimmten thread zu geschehen hat, sondern da arbeitet immer der, der gerade was braucht.evtl hängt zusätzlich ein anzeigethread rum, der alle userinteraktion aus einer hand zu machen hat. der kann natürlich auf die datenstrukturen von holeAufgabe und gibErgebnis auch zugreiifen. aber immer schön mit mutexen geschützt.
-
rom4o, hast du denn noch eine konkrete Frage?
-
jeder thread macht nur for(;;) { holeAufgabe(); rechne(); gibErgebnis(); }
Das ist eine sehr gute Idee und ich werde versuchen das so zu implementieren.
Jedoch habe ich erstmal ein grundlegendes Problem zu lösen.Hallo Leute ich habe nun mal in einem Programm versucht,
die Berechnung von Primzahlen auf zwei Threads aufzuteilen. So kann man dann die Threads
einzelnen CPU-Kernen zuordnen.
Mein Ziel ist ja immernoch den Prozessor komplett auszulasten.Hier der Code:
// prim_mutex_dualcore.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung. // #include "stdafx.h" #include <iostream> #include <windows.h> #include <math.h> using namespace std; SYSTEMTIME systime,systimeold; //time-variable int hDiff = 0; int mDiff = 0; int sDiff = 0; int msDiff = 0; int count = 1; // 1 weil die 2 nicht berechnet wird int c=3; int aim = 1000; //int aim = 2000000; HANDLE mutex = CreateMutex( NULL, FALSE, NULL ); void calcDiff() //Zeitschieber-Methode { hDiff = systime.wHour-systimeold.wHour; mDiff = systime.wMinute-systimeold.wMinute; sDiff = systime.wSecond-systimeold.wSecond; msDiff= systime.wMilliseconds-systimeold.wMilliseconds; if(msDiff<0){sDiff--; msDiff=msDiff+1000;} if(sDiff<0){mDiff--; sDiff=sDiff+60;} if(mDiff<0){hDiff--; mDiff=mDiff+60;} if(hDiff<0){hDiff=hDiff+24;} } bool Prim(int zahl) { bool devided = false; for(int k=3;k<(sqrt(zahl)+1);k=k+2) { if((zahl%k) == 0){ devided=true; k=zahl;} } return !devided; } DWORD WINAPI ThreadProc1( LPVOID pvoid ) { while(c<=aim) { if ( WaitForSingleObject( mutex, INFINITE ) == WAIT_OBJECT_0 ) // Mutex-Zugriff holen { if(Prim(c)) { cout << "T1" << " : " << c <<endl; // Ausgabe der Primzahl count++; } c=c+2; ReleaseMutex( mutex ); // Mutex wieder freigeben } // Sleep(10); } return 0; } DWORD WINAPI ThreadProc2( LPVOID pvoid ) { while(c<=aim) { if ( WaitForSingleObject( mutex, INFINITE ) == WAIT_OBJECT_0 ) // Mutex-Zugriff holen { if(Prim(c)) { cout << "T2" << " : " << c <<endl; // Ausgabe der Primzahl count++; } c=c+2; ReleaseMutex( mutex ); // Mutex wieder freigeben } // Sleep(3000); } return 0; } void main() { // Threads erzeugen GetSystemTime(&systimeold); //take time BEGIN cout << "Thread1 startet..."<<endl; DWORD dwThreadParam1 = 1; HANDLE hThread1 = CreateThread (NULL,0,ThreadProc1,&dwThreadParam1,0,NULL); SetThreadAffinityMask(hThread1, 1); cout << "Thread2 startet..."<<endl; DWORD dwThreadParam2 = 2; HANDLE hThread2 = CreateThread (NULL,0,ThreadProc2,&dwThreadParam2,0,NULL); SetThreadAffinityMask(hThread2, 2); // Auf Threads warten WaitForSingleObject( hThread1, INFINITE ); WaitForSingleObject( hThread2, INFINITE ); GetSystemTime(&systime); //take time END calcDiff(); cout << "Time: " << hDiff << ":" << mDiff << ":" << sDiff << ":" << msDiff << endl; cout << "Anzahl: " << count <<endl; // Thread-Handles schließen CloseHandle( hThread1 ); CloseHandle( hThread2 ); // Mutex zerstören CloseHandle( mutex ); TerminateThread (hThread1, 0); TerminateThread (hThread2, 0); }
Nun habe ich als globale Variable "c" genommen, welches von jedem Thread um 2 inkrementiert wird.
Diese Inkrementierung ist durch ein Mutex abgesichert.
Mein Problem ist nun, dass immer nur ein Thread rechnet weil er auf den anderen wartet.Wie kann ich dieses Problem lösen?
Mir fällt gerade überhaupt nichts ein.
Wenn man die Textausgabe weglässt, ist das Programm schon sehr schnell.Ich habe eine Timetake-Funktion eingebaut, die die Rechenzeit anzeigt.
Da wäre auch noch die Frage wie man in der Konsole die Integerwerte konvertiert ausgibt?
Jetzt ist die Ausgabe so: "Time: 0:0:12:287", ich will die aber so haben "Time: 00:00:12:287".Vielen Dank für Ratschläge.
grüße rom4o
-
rom4o schrieb:
Mein Problem ist nun, dass immer nur ein Thread rechnet weil er auf den anderen wartet.
Du brauchst den Funktionsaufruf von "Prim(c)" ja nicht mit dem Mutex zu schützen. Du könntest also den Mutex holen, den Wert von "c" in einer neuen temporären Variable speichern, "c" erhöhen und den Mutex zurückgeben. Dann führst du "if (Prim(old_c))" aus, währenddessen kann sich der andere Thread schon den Mutex holen.
Das Problem dabei wäre nur, dass die Konsolen-Ausgabe durcheinander-geraten kann. Eine Lösung dafür wäre, erst alle Primzahlen in einem Container (entweder auch durch einen Mutex abgesichert oder jeder Thread hat seinen eigenen Container, die am Schluss zusammengefügt werden) zu speichern und erst nach den ganzen Berechnungen auszugeben.
-
int getNextCandidate() { WaitForSingleObject( mutex, INFINITE ); c=c+2; int r=c; ReleaseMutex( mutex ); return c; } void printPrime( int prime ) { WaitForSingleObject( mutex, INFINITE ); cout<<prime<<' '; ReleaseMutex( mutex ); } bool Prim(int zahl) { bool devided = false; for(int k=3;k<(sqrt(zahl)+1);k=k+2) { if((zahl%k) == 0){ devided=true; k=zahl;} } return !devided; } DWORD WINAPI ThreadProc( LPVOID pvoid ) { int cc=getNextCandidate(); while(cc<=aim) { if(Prim(cc)) printPrime(cc); cc=getNextCandidate(); } return 0; }
-
Nimm OpenMP, das macht das Leben viel einfacher... keine Gedanken mehr über Mutexe verlieren...
Ab VS2010 siehe auch PPL...
-
Wo steht geschrieben, dass die GDI multiCPU-Fähig geschweige den Threadsafe ist?
Den Satz vermisse ich seit über 20 Jahren.
-
@Badestrand: hab mich nach deinem Tip schnell rangemacht das umzusetzen und
dann kam auch schon die Lösung von volkmar@Jochen Kalmbach
Ja werde mich auch bald damit beschäftigen, aber ich will erstmal versuchen alles was möglich ist aus der WinApi herauszuholen.@CStern
Ähm, habe ich das behauptet?
Aber die Zuordnung der einzelnen Threads zu spezifischen Kernen, müsste doch
theoretisch den Prozessor voll auslasten?
Ich habe auch in meinen Tests die cout-Ausgabe herausgenommen.Hallo volkmar,
danke für diese elegante Lösung.
Es funktioniert. Aber es ist nichts schneller als vorher.
Wenn ich die Ausgabe rausnehme ist zwar alles viel schneller aber nur halbe Prozessorauslastung.
Ich kann mir das jetzt nicht erklären? Irgendwas muss schief laufen.Dazu habe ich noch count++; in deine print-Methode eingebaut
Code:void printPrime( int prime ) { WaitForSingleObject( mutex, INFINITE ); cout<<prime<<" "; count++; ReleaseMutex( mutex ); }
Das Problem ist, dass manchmal einige Werte doppelt berechnet werden.
Ich habe mal mehrmals bis 2000000 berechnen lassen.
count kommt auf folgende Werte: 149123,149058,149081,149066...usw.
In einem Puffer könnte man natürlich die doppelten Ergebnisse aussortieren,
aber wie kann es zu dieser Doppelberechnung bei deiner Verteilung kommen?Vielen Dank wieder für Ideen.
Grüße rom4o
-
int getNextCandidate() { WaitForSingleObject( mutex, INFINITE ); int r=c; c=c+2; ReleaseMutex( mutex ); return r; }
Ich denke, so war's gemeint.
Und ich würde unterschiedliche Mutexe für c-Beschützung und Ausgabe nehmen.
-
evtl ist noch
volatile int c=3;
nötig.
-
Hallo, ja Badestrand das war das Problem.
Hätte selber drauf kommen müssen
Danke euch beiden für die Tips.
Das Problem mit der halben Prozessorauslastung ist mir allerdings immernoch
ein Rätsel.
Ich denke es muss einen tieferen Grund dafür geben.
Theoretisch müsste das Programm nun mit 100% Auslastung laufen,
da jeder der Threads nun immer zu rechnen hat.Also viele Grüße bb
rom4o
-
rom4o schrieb:
Theoretisch müsste das Programm nun mit 100% Auslastung laufen,
da jeder der Threads nun immer zu rechnen hat.Jaja, die Theorie
Kommentier mal die Zeile mit "cout << ..." aus, leider warten die Threads sehr lange auf die Ausgabe.
edit: Auskommentieren, damit du siehst, dass die Threads immer "lange" Zeit in der Ausgabe hängen.
-
BTW: Warum einen langsamen Mutex nutzen wenn es schnelle CriticalSections gibt?
-
@Badestrand: Ich habe ja, wie ich auch schon geschrieben habe, die Ausgabe zum Test herausgenommen. Dann läuft das Programm sehr viel schneller aber trotzdem nur mit halber Auslastung.
Für aim=200000 und mit 'cout<<prime<<" ";' braucht mein Laptop ca. 8sec.
Für aim=200000 und ohne cout braucht er nur knapp 1sec.@Martin Richter: Könnte sein, dass es daran liegt. Habe in anderen Artikeln auch schon gelesen, dass Mutex´s aufwendig und zeitraubend sind.
Ich habe leider keine Ahnung wie man Critical Section umgeht.
Hast du vielleicht ein kurzes Beispiel?Vielen Dank euch.
rom4o
-
Martin Richter schrieb:
BTW: Warum einen langsamen Mutex nutzen wenn es schnelle CriticalSections gibt?
Ich vergesse die Critical Sections oft
Bleibt Mutexen eigentlich noch ein anderes Einsatzgebiet als Interprocess-Synchro?
rom4o schrieb:
Ich habe leider keine Ahnung wie man Critical Section umgeht.
http://www.google.de/search?hl=de&q=critical+section&btnG=Google-Suche&meta=