2017-10-28 3 views
0

Kürzlich arbeitete ich an einem Echtzeit-CPP-Programm Volumen Rendering-Bild und einige andere Polygon-Geometrie angezeigt mit VTK gleichzeitig. In meinem Code, 4 vtkRenderer Objekte instanziiert diferent Arten von vtkProp Objekte in einer Art und Weise, wie zu enthalten:Wie verbessert man die Rendering-Geschwindigkeit eines VTK-Programms in CPP mit mehr als einem vtkRenderer Objekte mit mehr als einem CPU-Thread oder GPU-Karte?

auto renderer1 = vtkSmartPointer<vtkRenderer>::New(); 
auto renderer2 = vtkSmartPointer<vtkRenderer>::New(); 
auto renderer3 = vtkSmartPointer<vtkRenderer>::New(); 
auto renderer4 = vtkSmartPointer<vtkRenderer>::New(); 

auto vtkActor1 = vtkSmartPointer<vtkActor>::New(); 
auto vtkActor2 = vtkSmartPointer<vtkActor>::New(); 
auto vtkActor3 = vtkSmartPointer<vtkActor>::New(); 
auto vtkVolume4 = vtkSmartPointer<vtkVolume>::New(); 

renderer1->AddActor(vtkActor1); 
renderer2->AddActor(vtkActor2); 
renderer3->AddActor(vtkActor3); 
renderer4->AddVolume(vtkVolume4); 

auto window1 = vtkSmartPointer<vtkRenderWindow>::New(); 
auto window2 = vtkSmartPointer<vtkRenderWindow>::New(); 
auto window3 = vtkSmartPointer<vtkRenderWindow>::New(); 
auto window4 = vtkSmartPointer<vtkRenderWindow>::New(); 
window1->AddRenderer(renderer1); 
window2->AddRenderer(renderer2); 
window3->AddRenderer(renderer3); 
window4->AddRenderer(renderer4); 

4 Timer von QTWidget werden Rendering diese Fenster erstellt wie die Zeit vergeht. Es ist sehr enttäuscht, dass die Geschwindigkeit des Programms in einer Workstation mit einem Intel CORE I9 CPU und 2 Nvidia GTX 1080 TI (im SlI-Modus) fast keinen Unterschied hat, in einem Laptop enthält ein Intel CORE I5 und eine Nvidia GeForce 940mx. .. Das Rendering von window1 zu window3 wird teilweise durch die Ray-Casting-Berechnung in window4 blockiert. Andererseits wird das Blockierungsproblem von window1 zu window3 überwunden, sobald das Fenster 4 für Ray-Casting-Rendering deaktiviert ist. Um die Geschwindigkeit des Renderings zu verbessern und die vollen Vorteile der I9 CPU und der doppelten GTX 1080 TI zu nutzen. Zu diesem Zeitpunkt 4 std :: thread werden verwendet, um zu versuchen, diese verschiedenen Fenster auf anderen Thread in einer Art und Weise zu machen, wie:

auto thread1 = new std::thread([&]() 
{ 
    while (1) 
    { 
     std::this_thread::sleep_for(std::chrono::milliseconds(10)); 
     window1->Render(); 
    } 
}); 
thread1->detach(); 
auto thread2 = new std::thread([&]() 
{ 
    while (1) 
    { 
     std::this_thread::sleep_for(std::chrono::milliseconds(10)); 
     window2->Render(); 
    } 
}); 
thread2->detach(); 
auto thread3 = new std::thread([&]() 
{ 
    while (1) 
    { 
     std::this_thread::sleep_for(std::chrono::milliseconds(10)); 
     window3->Render(); 
    } 
}); 
thread3->detach(); 
auto thread4 = new std::thread([&]() 
{ 
    while (1) 
    { 
     std::this_thread::sleep_for(std::chrono::milliseconds(10)); 
     window4->Render(); 
    } 
}); 
thread4->detach(); 

Auf diese Weise scheint es, dass das Blockierungsproblem von window1 zu window3 sind verschwunden. Wenn die Mausaktion in einem beliebigen Fenster angewendet wird, wird Vtk-Laufzeitfehler: "FEHLER: In D: \ vtk7 \ VTK-7.1.1 \ Rendering \ OpenGL \ vtkWin32OpenGLRenderWindow.cxx Zeile 278 vtkWin32OpenGLRenderWindow (000002663199C870): WglMakeCurrent in fehlgeschlagen MakeCurrent(), Fehler: " wird generiert und das Programm wird nach einer zufälligen Zeit abgestürzt sein.

Zu dieser Zeit bin ich verwirrt, wie man verschiedene Render-Fenster sicher bei verschiedenen CPU-Thread gerendert. Eine alternative Lösung könnte sein, dass das Rendering von window4 raycasting auf einer Nvidia GTX 1080 TI und das Rendern von window1 to window3 (ohne Ray-Casting) auf eine andere Nvidia GTX 1080 TI angewendet wird. Unterstützt VTK den oben beschriebenen Arbeitsmodus? Wie erreiche ich das?

+0

Multihreading OpenGL-Aufrufe ist selten eine gute Idee, siehe z. Diese Frage https://StackOverflow.com/Questions/11097170 oder Google "OpenGL Multithreading-Rendering" für weitere Informationen. Die GPU lässt jedes Rendering so schnell wie möglich passieren, aber es kann immer nur eins tun - parallele openGL-Aufrufe führen nicht dazu, dass es gleichzeitig zwei Durchgänge macht, so dass Sie keine echte Parallelität erhalten -> Du bekommst so keine Beschleunigung. Alles, was du bekommst, ist ein zusätzlicher Overhead von wechselnden Kontexten (du zwingst die GPU in vier verschiedene Puffer zu rendern) und eine große Race Condition ... – tomj

Antwort

0

Sie können nicht mit den VTK-GUI-Klassen wie vtkRenderWindow von außerhalb des Hauptthreads interagieren, dem Thread, in dem die Ereignisverteilung stattfindet. Wenn Sie das tun, passieren alle möglichen Fehler.

Auch habe ich noch nie ein Programm gesehen, wo eine HWND-Komponente mit einer GPU gerendert wird und die anderen mit einer anderen und, soweit ich weiß, die für Ihr Programm zur Verfügung stehende GPU wird beim Start gesetzt, wie in diesen Notebooks mit zwei GPUs. Der einzige Weg, dies zu tun, wäre, soweit ich weiß, die Verwendung von OpenCL und das Raycasting in einer GPU und das Rendern in einer anderen GPU, aber es gibt keinen solchen Volume-Renderer in VTK.

Verwandte Themen