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