<div dir="ltr">Hi Julien,<div><br></div><div>I am happy to hear that it wasn't my code behind the performance issue :-)</div><div><br></div><div>I have plans to revise the pipeline passes. The main idea is to reduce the number of passes by propagating request on the upstream of a pass while propagating data (or meta-data) during the downstream. Something like:</div>
<div><br></div><div>- RequestInformation</div><div>- RequestTime / RequestDynamicMetaData</div><div>- RequestUpdateExtent / RequestData</div><div><br></div><div>Although the main reason behind this is correctness (the current approach has a flaw in it), it should improve performance also. Also, it is possible certain checks are being performed more than necessary so that needs to be tracked down.</div>
<div><br></div><div>In summary, I would leave things as they are in the short term and live with the performance problem. Once I am done with my changes, upgrading to the next version of VTK (which should be painless since there are no planned API changes) should address the issue.</div>
<div><br></div><div>If this is not an option, we can find a way to short-circuit those time passes.</div><div><br></div><div>Best,</div><div>-berk</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, May 14, 2014 at 12:06 PM, Julien Finet <span dir="ltr"><<a href="mailto:julien.finet@kitware.com" target="_blank">julien.finet@kitware.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<div><br></div><div>I have noticed a decrease in performance when switching from VTK5 to VTK6.</div>
<div>
This is related to the number of actors in the scene and the pipeline updates.</div><div><br></div>
<div>Here I use VTK Rendering TimeRenderer test to compare the 2 versions. To average the timing, the render loop has been increased from 360 to 3600 iterations. Here are some results:</div><div> VTK 5: 100 actors: 13.5s</div>
<div> VTK 6: 100 actors: 13.5s (100%)</div><div> VTK 5: 300 actors: 13.1s</div><div> VTK 6: 300 actors: 15.6s (115%)</div><div> VTK 5: 600 actors: 13.1s</div><div> VTK 6: 600 actors: 21.3s (163%)</div><div> VTK 5: 1000 actors: 15.1s</div>
<div> VTK 6: 1000 actors: 33.5s (222%)</div><div><br></div><div>A simpler test that only calls GetBounds() multiple times on a vtkPolyDataMapper produces the following time-ordered-backtraces:</div><div>VTK 5:</div><div>
<div>
Running Time<span style="white-space:pre-wrap"> </span>Self<span style="white-space:pre-wrap"> </span>Symbol Name</div><div>221.5ms 100.0%<span style="white-space:pre-wrap"> </span>0.6<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span>vtkPolyDataMapper::GetBounds()</div>
<div>122.0ms 55.0%<span style="white-space:pre-wrap"> </span>0.6<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::Update(int)</div>
<div>090.0ms 40.6%<span style="white-space:pre-wrap"> </span>0.4<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::UpdateInformation()</div>
<div>019.3ms 8.7%<span style="white-space:pre-wrap"> </span>1.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::PropagateUpdateExtent(int)</div>
<div>009.6ms 4.3%<span style="white-space:pre-wrap"> </span>1.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*)</div>
<div>001.0ms 0.4%<span style="white-space:pre-wrap"> </span>1.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutive::CheckAlgorithm(char const*, vtkInformation*)</div>
<div>000.4ms 0.1%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::UpdateData(int)</div>
<div>000.2ms 0.0%<span style="white-space:pre-wrap"> </span>0.2<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkAlgorithm::GetNumberOfOutputPorts()</div>
<div>000.2ms 0.0%<span style="white-space:pre-wrap"> </span>0.2<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformationIntegerKey::Set(vtkInformation*, int)</div>
<div>000.2ms 0.0%<span style="white-space:pre-wrap"> </span>0.2<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformation::Has(vtkInformationRequestKey*)</div>
<div>000.1ms 0.0%<span style="white-space:pre-wrap"> </span>0.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformationRequestKey::Has(vtkInformation*)</div>
<div>000.1ms 0.0%<span style="white-space:pre-wrap"> </span>0.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutive::GetOutputInformation()</div>
<div>000.1ms 0.0%<span style="white-space:pre-wrap"> </span>0.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()</div>
<div>000.0ms 0.0%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutiveInternals::GetInputInformation(int)</div>
<div>000.0ms 0.0%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::UpdateDataObject()</div>
<div>000.0ms 0.0%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*)</div>
<div>000.0ms 0.0%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::REQUEST_DATA()</div>
<div>064.2ms 28.9%<span style="white-space:pre-wrap"> </span>1.7<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkPolyDataMapper::Update()</div>
<div>027.5ms 12.4%<span style="white-space:pre-wrap"> </span>1.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkPainterPolyDataMapper::ComputeBounds()</div>
<div>002.1ms 0.9%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutive::GetNumberOfInputConnections(int)</div>
<div>000.8ms 0.3%<span style="white-space:pre-wrap"> </span>0.8<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkClipPlanesPainter::UpdateBounds(double*)</div>
<div>000.7ms 0.3%<span style="white-space:pre-wrap"> </span>0.7<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkPainter::GetDelegatePainter()<br>
</div><div>000.6ms 0.2%<span style="white-space:pre-wrap"> </span>0.6<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDataObject::SetUpdateExtent(int, int, int)</div>
<div>000.5ms 0.2%<span style="white-space:pre-wrap"> </span>0.4<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkPainter::UpdateBounds(double*)</div>
</div><div><br></div><div>VTK 6:</div><div><div><div>Running Time<span style="white-space:pre-wrap"> </span>Self<span style="white-space:pre-wrap"> </span>Symbol Name</div><div>1077.5ms 100.0%<span style="white-space:pre-wrap"> </span>2.6<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span>vtkPolyDataMapper::GetBounds()</div>
<div>846.6ms 78.5%<span style="white-space:pre-wrap"> </span>0.7<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::Update(int)</div>
<div>335.7ms 31.1%<span style="white-space:pre-wrap"> </span>2.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::PropagateTime(int)</div>
<div>298.3ms 27.6%<span style="white-space:pre-wrap"> </span>1.3<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::UpdateTimeDependentInformation(int)</div>
<div>123.8ms 11.4%<span style="white-space:pre-wrap"> </span>1.4<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::PropagateUpdateExtent(int)</div>
<div>068.4ms 6.3%<span style="white-space:pre-wrap"> </span>0.4<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::UpdateInformation()</div>
<div>009.2ms 0.8%<span style="white-space:pre-wrap"> </span>1.6<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*)</div>
<div>000.6ms 0.0%<span style="white-space:pre-wrap"> </span>0.6<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformationIntegerKey::Set(vtkInformation*, int)<br>
</div><div>000.5ms 0.0%<span style="white-space:pre-wrap"> </span>0.5<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutive::GetOutputInformation()</div>
<div>000.4ms 0.0%<span style="white-space:pre-wrap"> </span>0.4<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformation::Set(vtkInformationRequestKey*)</div>
<div>000.4ms 0.0%<span style="white-space:pre-wrap"> </span>0.4<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformationRequestKey::Set(vtkInformation*)</div>
<div>000.3ms 0.0%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::UpdateData(int)</div>
<div>000.3ms 0.0%<span style="white-space:pre-wrap"> </span>0.3<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformation::Set(vtkInformationIntegerKey*, int)</div>
<div>000.3ms 0.0%<span style="white-space:pre-wrap"> </span>0.3<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkAlgorithm::GetNumberOfOutputPorts()</div>
<div>000.2ms 0.0%<span style="white-space:pre-wrap"> </span>0.2<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformation::Has(vtkInformationRequestKey*)</div>
<div>000.2ms 0.0%<span style="white-space:pre-wrap"> </span>0.2<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutiveInternals::GetInputInformation(int)</div>
<div>000.1ms 0.0%<span style="white-space:pre-wrap"> </span>0.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutive::CheckAlgorithm(char const*, vtkInformation*)</div>
<div>000.1ms 0.0%<span style="white-space:pre-wrap"> </span>0.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::UpdateDataObject()</div>
<div>000.1ms 0.0%<span style="white-space:pre-wrap"> </span>0.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*)</div>
<div>000.1ms 0.0%<span style="white-space:pre-wrap"> </span>0.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkInformationRequestKey::Has(vtkInformation*)</div>
<div>000.0ms 0.0%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutive::GetInputInformation()</div>
<div>0080.8ms 7.4%<span style="white-space:pre-wrap"> </span>0.8<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkDemandDrivenPipeline::UpdateInformation()</div>
<div>0048.6ms 4.5%<span style="white-space:pre-wrap"> </span>1.2<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkPainterPolyDataMapper::ComputeBounds()</div>
<div>0030.5ms 2.8%<span style="white-space:pre-wrap"> </span>1.9<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::SetUpdateExtent(vtkInformation*, int, int, int)</div>
<div>0021.7ms 2.0%<span style="white-space:pre-wrap"> </span>0.6<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkAlgorithm::GetInputAlgorithm(int, int)</div>
<div>0010.3ms 0.9%<span style="white-space:pre-wrap"> </span>2.2<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkStreamingDemandDrivenPipeline::ProcessRequest(vtkInformation*, vtkInformationVector**, vtkInformationVector*)</div>
<div>007.5ms 0.6%<span style="white-space:pre-wrap"> </span>4.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkPainter::UpdateBounds(double*)</div>
<div>005.8ms 0.5%<span style="white-space:pre-wrap"> </span>1.2<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkAlgorithm::GetInputInformation(int, int)</div>
<div>005.2ms 0.4%<span style="white-space:pre-wrap"> </span>0.9<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkAlgorithm::UpdateInformation()</div>
<div>002.4ms 0.2%<span style="white-space:pre-wrap"> </span>0.1<span style="white-space:pre-wrap"> </span> <span style="white-space:pre-wrap"> </span><span style="white-space:pre-wrap"> </span>vtkExecutive::GetNumberOfInputConnections(int)</div>
</div></div><div><br></div><div><br></div><div>Calling SetStatic() on all the mappers improve things:</div><div> VTK 5: 100 actors: 6.7s</div><div> VTK 6: 100 actors: 6.7s (100%)</div><div> VTK 5: 1000 actors: 6.7s</div>
<div>
VTK 6: 1000 actors: 8.4s (125%)</div><div>While the performance is still hit, it is more acceptable. However, for my use case, making my mappers static is not an option. </div><div><br></div><div>A hack to disable the time propagation also improve things a bit:</div>
<div><div> VTK 5: 100 actors: 6.7s</div><div> VTK 6: 100 actors: 6.7s (100%)</div><div> VTK 5: 1000 actors: 15.1s</div><div> VTK 6: 1000 actors: 20.0s (132%)</div></div><div>While time propagation is responsible for a large part of the slowness, it still does not explain 100% of the performance decrease.</div>
<div><br></div><div>Any suggestion ? </div><div>As a quick fix, we could improve the "Static" property of the mappers by specifying if the mapper input is "time static" (e.g. vtkMapper::SetStatic(2) or vtkMapper::SetTimeStatic(1)).</div>
<div><br></div><div>Thanks,</div><div>Julien.</div><div>p.s. TimeRenderer currently segfaults in VTK6 trunk due to a missing auto-initialization.</div></div>
<br>_______________________________________________<br>
Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://www.vtk.org/mailman/listinfo/vtk-developers" target="_blank">http://www.vtk.org/mailman/listinfo/vtk-developers</a><br>
<br>
<br></blockquote></div><br></div>