Avatar ·

Ersetzen eines 32-Bit-Schleifenzählers durch einen 64-Bit verursacht seltsame Leistungseinbußen mit _mm_popcnt_u64 auf Intel CPUs

Hallo zusammen! Ich schreibe ein C++-Programm zum Zählen von gesetzten Bits in einem großen Datenarray. Ich verwende die intrinsische Funktion _mm_popcnt_u64 aus dem SSE4.2-Set. Der Code ist einfach: Ich durchlaufe ein uint64_t-Array und akkumuliere das Ergebnis. Alles funktioniert einwandfrei, aber mir ist eine seltsame Sache aufgefallen: Wenn ich den Typ des Schleifenzählers von 32-Bit (unsigned int) auf 64-Bit (size_t) ändere, sinkt die Leistung um das 2- bis 3-fache! Dabei sind die Daten gleich, die Array-Größe gleich, der Compiler gleich (MSVC 2019, Flags /O2 /arch:AVX2). Hier ist der vereinfachte Code: #include #include #include #include int main() { const size_t N = 1'000'000; std::vector data(N, 0xFFFFFFFFFFFFFFFF); // alle Bits = 1 // Version 1: 32-Bit-Zähler unsigned int sum32 = 0; auto t1 = std::chrono::high_resolution_clock::now(); for (unsigned int i = 0; i < data.size(); ++i) { sum32 += _mm_popcnt_u64(data[i]); } auto t2 = std::chrono::high_resolution_clock::n