Heath Feather wrote:
>  
> 
> Massive perfomance hit in Qt's reference counting system caused by 
> qgl.cpp:qt_gl_clean_cache().
> 
>  
> 
> I was recently using the QImage::setPixel() function to populate a 
> QImage , and discovered that it seemd to be extremely slow. Upon further 
> inspection I found that it called the detach() function, which in turn 
> eventually called a very strange qgl.cpp:qt_gl_clean_cache() function.
> 
>  
> 
> When just one OpenGL texture is bound the performance of setPixel() 
> drops from its already pretty poor performance , to about 100x slower. 
> In fact any Qt operations which make use of the detach() method suffer 
> this indignity. The more textures that are bound the more the 
> performance hit increase.
> 
>  
> 
> My little million QImage::setpixel() calls take 0.04 seconds when no 
> OpenGL textures are bound and 9 seconds when 5 textures are bound.
> 
>  
> 
> If you take a look at the OpenGL Texture Cache architecture and the 
> qt_gl_clean_cache() function in particular , you will note that it 
> unrolls a QCache, creates a QList , depends on sprintf based Qstring 
> keys , and then linearly runs through it doing substring comparisons. 
> This seems like a function that was never expected to go into 
> production, since it is extremely sub optimal, and all sorts of areas of 
> Qt are ultimately suffering because of it.
> 
>  
> 
> 1 million QImage::setPixel() calls   .042 sec,  with 5 OpenGL textures   
> 8.8 sec (209x slower)    
> 
> 1 million QImage::setPixel() calls   .042 sec,  with 10 OpenGL textures 
> 12.4 sec (295x slower)    
> 
> 1 million QImage::setPixel() calls   .042 sec,  with 50 OpenGL textures 
> 26.5 sec (630x slower)    
> 
>  
> 
> I have attached a small program which exhibits the issue.
> 
>  
> 
>  
> 
> List of Issues
> 
> ==============
> 
> QImage::SetPixel() calls detach() twice , once within itself, and ones 
> via scanLine(); the second call via scanLine should be removed. Maybe an 
> internal scanLine() method without the detach, such as the existing 
> const version.
> 
>  
> 
> qt_gl_clean_cache() maintains a QString based Hash, which is then 
> decomposed into a list traversed linearly. This needs to be changed, the 
> string based key is expensive to create , and then the linear traversal 
> and QList is both odd and tremendously expensive.
> 
>  
> 
>  
> 
> Qt4.4 Linux X86-64, also in earlier versions such as Qt4.3.3
> 
>  
> 
> Thanks,
> 
>  
> 
> Heath Feather
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Qt4-preview-feedback mailing list
> [email protected]
> http://lists.trolltech.com/mailman/listinfo/qt4-preview-feedback

Hello Heath,

indeed, setPixel() seems to be unnecessary slow, and we will look into 
ways of optimizing the qt_gl_clean_cache() function to avoid this huge 
additional cost when textures are bound. However, setPixel is arguably 
not the best choice when doing pixel manipulation both due to the extra 
function call and the repeated work that needs to be done there. If 
performance is a concern I would recommend you to use the scanLine() or 
bits() function to reduce the number of function calls to once per row 
of pixels or once for all the rows.

Regards,

Samuel Rødal

_______________________________________________
Qt4-preview-feedback mailing list
[email protected]
http://lists.trolltech.com/mailman/listinfo/qt4-preview-feedback

Reply via email to