Avatar ·

Ersetzen eines 32-Bit-Schleifenzählers durch einen 64-Bit-Zähler verursacht seltsame Leistungssprünge mit _mm_popcnt_u64 auf Intel-CPUs

Hallo zusammen! Ich schreibe eine hochleistungsfähige Funktion zum Zählen von Einzelbits (popcount) in einem großen Array von 64-Bit-Ganzzahlen. Ich verwende das Intrinsic `_mm_popcnt_u64` aus SSE4.2. Der Code ist einfach – eine Schleife, die den popcount für jedes Element summiert. Ich habe ein seltsames Verhalten festgestellt: Wenn die Schleifenvariable als `uint32_t` deklariert wird, arbeitet die Funktion sehr schnell. Aber wenn ich sie auf `uint64_t` ändere (einfach durch Ändern des Typs von `i`), fällt die Leistung um fast die Hälfte! Ich habe dies auf mehreren Intel Core i7 (Sandy Bridge, Haswell, Skylake) getestet – der Effekt tritt auf. Der Compiler ist MSVC 2010, obwohl bei GCC 4.6.3 ein ähnliches Bild zu sehen ist. Optimierungen sind aktiviert (/O2 oder -O2). Hier ist ein minimales Codebeispiel: ```cpp #include #include #include #include // Schnelle Version mit 32-Bit-Zähler uint64_t popcnt32(const uint64_t* data, size_t size) { uint64_t result = 0; for (uint32_t i = 0; i < size; ++i) { // <-- 32-bit result += _mm_popcnt_u64(data[i