2010-01-30 10 views
14

Ich erstelle eine Anwendung, die eine Objektverfolgung anhand eines Videokamera-Feeds durchführt und Informationen dazu verwendet, um ein Partikelsystem in OpenGL auszuführen. Der Code zum Verarbeiten des Video-Feeds ist etwas langsam, 200 bis 300 Millisekunden pro Frame im Moment. Das System, auf dem es ausgeführt wird, verfügt über einen Dual-Core-Prozessor. Um die Leistung zu maximieren, möchte ich die Verarbeitung der Kamera auf einen Prozessor verlagern und nur die relevanten Daten an die Hauptanwendung weitergeben, so wie sie verfügbar ist, während die Hauptanwendung auf dem anderen Prozessor bleibt.So strukturieren Sie eine C++ - Anwendung für die Verwendung eines Multicore-Prozessors

Was muss ich tun, um die Kamera auf den anderen Prozessor auszulagern und wie handhabe ich die Kommunikation mit der Hauptanwendung?

Edit: Ich verwende Windows 7 64-Bit.

Antwort

12

Grundsätzlich müssen Sie Ihre Anwendung Multithread. Jeder Thread der Ausführung kann nur einen Kern sättigen. Separate Gewinde werden normalerweise auf separaten Kernen geführt. Wenn Sie darauf bestehen, dass jeder Thread IMMER auf einem bestimmten Kern ausgeführt wird, dann hat jedes Betriebssystem seine eigene Art, dies zu spezifizieren (Affinitätsmasken & so) ... aber ich würde es nicht empfehlen.

OpenMP ist großartig, aber es ist ein bisschen Fett in den Arsch, vor allem, wenn Sie sich von einer Parallelisierung zurück zu verbinden. YMMV. Es ist einfach zu bedienen, aber nicht die beste Option. Es erfordert auch Compiler-Unterstützung. Wenn Sie unter Mac OS X 10.6 (Snow Leopard) arbeiten, können Sie Grand Central Dispatch verwenden. Es ist interessant darüber zu lesen, auch wenn Sie es nicht verwenden, da das Design einige Best Practices implementiert. Es ist auch nicht optimal, aber es ist besser als OpenMP, obwohl es auch Compiler-Unterstützung benötigt.

Wenn Sie Ihre Anwendung in "Tasks" oder "Jobs" aufteilen können, können Sie diese Jobs um so viele Pipes verschieben, wie Sie Kerne haben. Stellen Sie sich die Verarbeitung als atomare Arbeitseinheiten vor. Wenn Sie es richtig segmentieren können, können Sie Ihre Kameraverarbeitung auf beiden Kernen und gleichzeitig auf Ihrem Haupt-Thread ausführen.

Wenn die Kommunikation für jede Arbeitseinheit minimiert wird, werden die Mutexe und andere Sperrgrundelemente minimiert. Grobkörniges Threading ist viel einfacher als feinkörniges. Und Sie können immer eine Bibliothek oder ein Framework verwenden, um die Belastung zu verringern. Betrachten Sie Boost's Thread library, wenn Sie den manuellen Ansatz nehmen. Es bietet portable Wrapper und eine schöne Abstraktion.

1

Sie benötigen eine Art Framework für den Umgang mit Multicores. OpenMP scheint eine ziemlich einfache Wahl.

+2

Sie könnten auch einfach Pthreads oder was auch immer das OS bereits bietet. – pestilence669

+1

@Pestilence - ja, obwohl ich dabei bin, plattformübergreifende Lösungen vorzuschlagen :) –

+0

lol. Pthreads auf Cygwin dann! :) – pestilence669

2

Ich würde gegen OpenMP empfehlen, OpenMP ist mehr für numerische Codes als Verbraucher/Hersteller-Modell, das Sie zu haben scheinen.

Ich denke, Sie können etwas Einfaches mit Boost-Threads tun, um Arbeiter Thread spawn, gemeinsamen Segment des Speichers (für die Kommunikation von erfassten Daten), und einige Benachrichtigung Mechanismus auf Ihre Daten zu informieren ist verfügbar (siehe boost Thread Interrupts).

Ich weiß nicht, welche Art von Verarbeitung Sie tun, aber vielleicht möchten Sie einen Blick auf die Intel-Thread-Bausteine ​​und integrierten Intel-Primitiven werfen, sie haben mehrere Funktionen für die Videoverarbeitung, die schneller sein können (vorausgesetzt, sie haben Ihre Funktionalität)

+0

In Anbetracht der Tatsache, dass eine Trennung zwischen Verbraucher und Hersteller würde fast nichts in Bezug auf Effizienz gewinnen, ich denke, er wird sowieso parallel Verarbeitung der Kameradaten benötigen. Und es gibt keine einfache Möglichkeit, zu garantieren, dass ein zweiter boost :: -Thread sowieso auf dem anderen Kern erscheinen wird ... –

+0

MPI wäre in diesem Fall praktikabler, denke ich. – tur1ng

+0

ohne die Details zu wissen, ist es schwer zu sagen, aber im Allgemeinen stimme ich Ihnen zu. In Linux land gibt es ein cpuset-Dienstprogramm, das die Thread-Platzierung steuert, habe es aber selbst nicht benutzt. Meiner Meinung nach wäre MPI ein Overkill, ich denke nicht, dass Mr. Bell beabsichtigt, auf mehreren Knoten zu laufen. – Anycorn

1

Es hängt davon ab, wie viele Kerne Sie haben. Wenn Sie nur 2 Kerne haben (CPU, Prozessoren, Hyperthreads, Sie wissen, was ich meine), dann kann OpenMP nicht so eine enorme Leistungssteigerung bieten, aber es wird Ihnen helfen.Die maximale Verstärkung, die Sie haben können, ist Ihre Zeit durch die Anzahl der Prozessoren zu teilen, so dass es immer noch 100 - 150 ms pro Frame dauert.

Die Gleichung ist
parallel Zeit = (([Gesamtzeit, um eine Aufgabe auszuführen] - [Code, parallelisiert werden kann])/[Anzahl der CPUs]) + [Code, der nicht parallelisiert werden kann]

Grundsätzlich rockt OpenMP bei parallelen Schleifen. Es ist sehr einfach zu bedienen

#pragma omp parallel for 
for (i = 0; i < N; i++) 
    a[i] = 2 * i; 

und bang, Ihr für ist parallelisiert. Es funktioniert nicht für jeden Fall, nicht jeder Algorithmus kann auf diese Weise parallelisiert werden, aber viele können neu geschrieben (gehackt) werden, um kompatibel zu sein. Das Schlüsselprinzip ist Single Instruction, Multiple Data (SIMD), wobei derselbe Faltungscode beispielsweise auf mehrere Pixel angewendet wird.

Aber die einfache Anwendung dieses Kochbuchs widerspricht den Regeln der Optimierung.
1-Benchmark Code
2-Die REAL Engpässe mit „wissenschaftlichen“ Beweis (Zahlen), anstatt einfach zu erraten, wo Sie denken, es einen Engpass
3-Wenn es wirklich Schleifen Verarbeitung ist, dann OpenMP für Sie

Vielleicht einfache Optimierungen auf Ihrem vorhandenen Code können bessere Ergebnisse geben, wer weiß?

Eine andere Straße wäre OpenGL in einem Thread und Datenverarbeitung auf einem anderen Thread zu laufen. Dies wird sehr hilfreich sein, wenn opengl oder Ihr Partikel-Rendering-System viel Energie verbraucht, aber denken Sie daran, dass Threading zu anderen Arten von Synchronisationsengpässen führen kann.

0

Wie Pestlence sagte, Sie brauchen nur Ihre App Multithread sein. Viele Frameworks wie OpenMP sind erwähnt worden, also hier ist ein anderes:

Intel Thread Building Blocks

ich es noch nie zuvor benutzt habe, aber ich höre große Dinge über sie.

Hoffe, das hilft!