2016-06-02 3 views
1

Ich verwende benchmark.js, um zwei Versionen einer Funktion zu takten, eine in JS und eine in C++ (eine node.js-Bindung).Benchmark über der CPU-Frequenz

Die C++ Version ist ein for-Schleife mit einem einzigen Compiler intrinsischen (2 Zyklus Latenz + 0,5 Zyklus Durchsatz):

for (size_t i = 0; i < arrlen; i++) { 
#if defined(_MSC_VER) 
    (*events)[i] = _byteswap_ushort((*events)[i]); 
#elif defined(__GNUC__) 
    (*events)[i] = __builtin_bswap16((*events)[i]); 
#endif 
} 

ich erwarte, dass es schnell sein ... aber es ist Taktung schneller als meine CPU-Frequenz (4,0 GHz). Wie kann das passieren? (Ich habe getestet, dass die Funktion außerhalb der Benchmark-Suite funktioniert.)

native: 17,253,787,071 elements/sec (10k elements in array * 1,725,379 calls/sec) 
JS: 846,298,297 elements/sec (10k elements in array * 84,630 calls/sec) 
// both ~90 runs sampled 
+3

Vektorisierung und [superscalar Verarbeitung] (https://en.wikipedia.org/wiki/Superscalar_processor). – Cornstalks

Antwort

2

Fest genau ohne mehr Kontext zu sagen, aber wahrscheinlich einen oder mehrere der folgenden Optionen:

  • Der Compiler verwendet wird Anweisungen wie PSHUFB zu Byte-Swap mehr als ein Element gleichzeitig. (PSHUFB kann auf Prozessoren mit AVX2-Unterstützung potenziell bis zu 16 Wörter gleichzeitig austauschen.)

  • Durch die Pipelineeffekte kann der Prozessor mehrere Iterationen dieser Schleife gleichzeitig verarbeiten.

  • Es gibt ein Problem mit Ihrem Benchmark, das es ermöglicht, die gesamte Berechnung zu optimieren. (Unwahrscheinlich, aber erwähnenswert.)

+0

Ich dachte nicht, die Demontage zu betrachten. Sie haben recht, es verwendet PSHUFB mit einem 128-Bit-Register (das hat auch eine bessere Latenz und einen besseren Durchsatz als bswap). Ziemlich erstaunliche Anweisung. – ZachB