Multiprozessor
-
Ich möchte Bilder um 180 Grad drehen und eine Farbkorrektur vornehmen. Das ganze an an 36 Bildern die 1024x1536 Pixel gross sind. Die Geschwindigkeit ist sehr wichtig.
Der Code sieht so aus:Graphics::TBitmap *bmp = new Graphics::TBitmap(); TJPEGImage *jpg = new TJPEGImage(); try { RGBTRIPLE CorRGB[256]; for(int i=0; i < 256; i++) { CorRGB[i].rgbtRed = pow(((float)i / 255),(1 / ControlThread->Red)) * 255; CorRGB[i].rgbtGreen = pow(((float)i / 255),(1 / ControlThread->Green)) * 255; CorRGB[i].rgbtBlue = pow(((float)i / 255),(1 / ControlThread->Blue)) * 255; } RGBTRIPLE *ptr, *ptr1, Cor; jpg->LoadFromFile(ControlThread->FileName); bmp->Assign(jpg); for (int y = 0; y < bmp->Height / 2; y++) { ptr = static_cast<RGBTRIPLE*>(bmp->ScanLine[y]); ptr1 = static_cast<RGBTRIPLE*>(bmp->ScanLine[bmp->Height - 1 - y]); for(int i = 0; i < bmp->Width; i++) { Cor.rgbtRed = CorRGB[ptr[i].rgbtRed].rgbtRed; Cor.rgbtGreen = CorRGB[ptr[i].rgbtGreen].rgbtGreen; Cor.rgbtBlue = CorRGB[ptr[i].rgbtBlue].rgbtBlue; ptr[i].rgbtRed = CorRGB[ptr1[(bmp->Width - 1 - i)].rgbtRed].rgbtRed; ptr[i].rgbtGreen = CorRGB[ptr1[(bmp->Width - 1 - i)].rgbtGreen].rgbtGreen; ptr[i].rgbtBlue = CorRGB[ptr1[(bmp->Width - 1 - i)].rgbtBlue].rgbtBlue; ptr1[(bmp->Width - 1 - i)]= Cor; } } jpg->Assign(bmp); jpg->Compress(); jpg->CompressionQuality = ControlThread->Quality; jpg->SaveToFile(ControlThread->OutputDir + "\\" + IntToStr(ControlThread->InstancesOfCounterThread) + ".jpg"); } __finally { delete bmp; delete jpg; }
Das ganze läuft in einem TThread drin. Ich habe versucht zwei Threads mit einander laufen zu lassen, um meinen Doppelprozessor voll auszulasten. Jedoch läuft alles immer noch auf einem Prozessor.
void __fastcall TControlThread::Run() { TImageCor *pImageCor1 = new TImageCor(true); pImageCor1->Resume(); TImageCor *pImageCor2 = new TImageCor(true); pImageCor2->Resume(); }
Die Application selber läuft auf dem ersten Prozessor und der Thread auf dem zweiten. Wie bringe ich es nun fertig mit dem BCB5 das der eine Thread auf einem und der andere auf dem anderen Prozessor läuft? Vielen Dank für eure Hilfe.
-
Hi,
keine Ahnung, ich glaub nicht, dass man vorgeben kann, wo ein Thread laufen soll.
Aber zum Bitmap drehen ist das vielleicht gut:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_0iwe.asp
-
Das steht in der Hilfe drin, aber wie man's macht, habe ich nicht gefunden
Multiprocessing. If the system running your program has multiple processors, you can improve performance by dividing the work into several threads and letting them run simultaneously on separate processors.
-
hm,
das wird wohl Systemabhängig sein. Mit der VCL kommst du da nciht weiter. VIelleicht gibt es da was in der WinAPI.
Ich schieb dich mal dort hin, weil ich glaube, das dir dort besser geholfen werden kann.
Ach ja:
http://www.codetools.com/bitmap/rotatebyshear.aspist auch interessant...
-
[msdn]SetThreadAffinityMask[/msdn]
Ich würde allerdings dem System überlassen, auf welcher CPU ein Thread arbeitet, schließlich weiß das System besser, welche CPU grad frei ist...
-
Vielen Dank Hepi.
Dem System überlassen? Es laufen alle Threads, soviele ich auch mache, über den zweiten Prozessor. Leider sieht es so aus, das ich den Thread an msdn anpassen muss und den TThread von BCB vergessen muss. Oder es weiss jemand doch noch mehr?
-
Das System kann die Verteilung der Threads immer besser steuern als Du. Das, was Du beschreibst, hiesse, daß bereits beim Erstellen des Threads eine andere Mask gesetzt wird. Das glaube ich aber eher weniger. Du kannst ja versuchsweise mit GetProcessAffinityMask die erlaubten Prozessoren abfragen und diese per SetThreadAffinityMask zurücksetzen.
Solche Probleme haben meist eine ganz andere hausgemachte Gestalt. Greifen beispielsweise alle Threads auf eine gemeinsame Ressource zu? Für den Zugriff muß die Ressource gelockt werden. In diesem Fall kommen die anderen Threads sowieso nicht zum Zuge und müssen warten. Und der laufende Thread kann ohnehin nur auf einem Processor gleichzeitig laufen.
Das nächste Problem sind das häufige Anfordern und Löschen von Speicher. Das kostet Zeit. Du machst das hier z.B. mit new/ delete. Aber alle Deine news und deletes holen den Speicher vom selben Heap. Die Aufrufe müssen aus diesem Grunde serialisiert werden. Der Zugriff auf den Heap wird intern gelockt. Die Threads behakeln sich unter Umständen also auch hier ganz fürchterlich.
Untersuche Deine Anwendung mal ein wenig in diese Richtung. Eventuell gib es hier noch Nachbesserungsbedarf.
-
Sehr empfehlenswert ist in diesem Zusammenhang die Lektüre des Buches:
"Microsoft Windows Programmierung für Experten" von Jeffrey Richter
Microsoft Windows Programmierung für Experten | ISBN: 3860636154Dort wird haarklein bis ins Detail auf Multithreading, Synchronisation usw. eingegangen...
-
Vielen Dank für Eure Hilfe. Leider ist es zu Spät für Weihnachtswünsche, aber ich werde mir dieses Buch sicher noch beschaffen.