Performance von std::queue?



  • So, Problem gelöst: ich habe die Queue einfach mal durch einen selbstgeschriebenen Ringpuffer ersetzt - und siehe da das Ding rennt wie verrückt und komplett ohne Aussetzer.

    Mit anderen worten: die MSVC-STL-Queue-Implementierung ist schlichtweg katastrophal ineffizent...



  • Digger schrieb:

    Mit anderen worten: die MSVC-STL-Queue-Implementierung ist schlichtweg katastrophal ineffizent...

    glaub ich dir ohne code samt messung (und deinen ergebnissen) schlichtweg nicht.

    bb



  • Hmm...um welche MSVC-Version geht es hier? Wenn < 2010, definier in den Projekteinstellungen der Release-Konfiguration mal _SECURE_SCL=0. Wenn gar < 2005, dann wundert es mich so oder so überhaupt nicht.



  • seldon schrieb:

    Hmm...um welche MSVC-Version geht es hier? Wenn < 2010, definier in den Projekteinstellungen der Release-Konfiguration mal _SECURE_SCL=0. Wenn gar < 2005, dann wundert es mich so oder so überhaupt nicht.

    ist vermutlich egal, weil das in der relase-version bei so was keinen unterschied macht. oeder jedenfalls keinen so extremen...

    _SECURE_SCL=0 hat auch bisher nur in performance-tests mit containern merkbare unterschiede gemacht. ich setze immernoch ziemlich viel auf den debug-mode.



  • std::queue ist ein Container-Adapter und setzt per Default auf std::deque auf. std::deques Laufzeitverhalten wird von _SECURE_SCL beeinflusst, und vor MSVC 2010 ist die Voreinstellung _SECURE_SCL=1. Ich wäre ziemlich überrascht, wenn das nicht durchschlüge.



  • Ein selbst geschriebener Ringpuffer kann schon viel schneller sein als ne std::deque, je nach Anwendung.
    Wer z.B. ne std::deque<char> verwendet, muss sich nicht wundern, dass das mit nem selbstgewastelten Ringpuffer viel viel schneller geht.

    @Digger:
    Ich fände es auch interessant wie dein Code genau aussieht.
    Vielleicht bekommen wir ja raus wieso die std::deque in deinem Fall so viel langsamer ist. Mich interessiert sowas immer.



  • unskilled schrieb:

    Digger schrieb:

    Mit anderen worten: die MSVC-STL-Queue-Implementierung ist schlichtweg katastrophal ineffizent...

    glaub ich dir ohne code samt messung (und deinen ergebnissen) schlichtweg nicht.

    Aha. Ich ersetze in einer Applikation eine std::queue durch einen Ringbuffer, die entsprechenden Funktionsaufrufe bleiben an exakt den gleichen Stellen, der restliche Code ist auch unverändert und du glaubst das nicht. Dann bitte ich dich vielmals um Entschuldigung dafür, dass die Realität etwas ergeben hat, was deine offenbar heißgeliebte Firma Microsoft ein ganz klitzeklein wenig kritisiert. Ich werde versuchen, dich nie wieder mit solcherart Fakten zu verwirren.



  • Digger schrieb:

    Aha. Ich ersetze in einer Applikation eine std::queue durch einen Ringbuffer, die entsprechenden Funktionsaufrufe bleiben an exakt den gleichen Stellen, der restliche Code ist auch unverändert und du glaubst das nicht. Dann bitte ich dich vielmals um Entschuldigung dafür, dass die Realität etwas ergeben hat, was deine offenbar heißgeliebte Firma Microsoft ein ganz klitzeklein wenig kritisiert. Ich werde versuchen, dich nie wieder mit solcherart Fakten zu verwirren.

    Nein, im Allgemeinen funktioniert das nicht. So ein new/delete schafft man doch heutzutage mit unter 200 Takten und davon muß ein paar nur alle 4096 Bytes stattfinden. Macht einen Takt pro 20 Bytes. Andere Gründe. Cache-Lokalität, Debug-Heap(!), das genannte _SECURE_SCL, Locking, falsche Zielmaschine eingestellt, kein Inlining, andere Optimierungen auch abgestellt…
    Du hast irgendwelche besonderen Bedingungen vorliegen, die die queue lahm gemacht hatten. :xmas2:



  • Zur deque: In der STL von Visual C++ wird alle 16 Bytes eine Allokation gemacht.

    #define _DEQUESIZ	(sizeof (value_type) <= 1 ? 16 \
    	: sizeof (value_type) <= 2 ? 8 \
    	: sizeof (value_type) <= 4 ? 4 \
    	: sizeof (value_type) <= 8 ? 2 \
    	: 1)	/* elements per block (a power of 2) */
    

    Finde ich ziemlich unakzeptabel.



  • Einen Ringpuffer kann man immerhin - je nach Implementierung - auch lockfree gestalten.



  • Ethon schrieb:

    Einen Ringpuffer kann man immerhin - je nach Implementierung - auch lockfree gestalten.

    AFAIK hat ein Ringpuffer eine feste Größe und ist somit praxisfremd.



  • hide schrieb:

    Ethon schrieb:

    Einen Ringpuffer kann man immerhin - je nach Implementierung - auch lockfree gestalten.

    AFAIK hat ein Ringpuffer eine feste Größe und ist somit praxisfremd.

    Nö muss nicht. Wenn der voll ist, kannsten ja trotzdem vergrößern.



  • Lockfree wäre in erster Linie sowieso ein verlinkter Ringpuffer, praktisch eine linked-list bei der erstes und letztes Element verkettet sind. Eigentlich eine relativ übliche Implementierung einer linked-list. Lässt sich mit primitiven atomaren Operationen thread-safe halten.


Anmelden zum Antworten