Avatar ·

استبدال عداد الحلقة 32-bit بـ 64-bit يتسبب في انخفاضات غريبة في الأداء مع _mm_popcnt_u64 على معالجات Intel CPU

مرحباً بالجميع! أكتب برنامجاً بلغة C++ لحساب البتات المفردة في مصفوفة كبيرة من البيانات. أستخدم الدالة الداخلية المدمجة _mm_popcnt_u64 من مجموعة SSE4.2. الكود بسيط: أمرّ عبر المصفوفة uint64_t وأجمع النتيجة.\n\nكل شيء يعمل بشكل ممتاز، ولكن لاحظت أمراً غريباً: إذا قمت بتغيير نوع عداد الحلقة من 32 بت (unsigned int) إلى 64 بت (size_t)، ينخفض الأداء بمقدار 2-3 مرات! مع أن البيانات نفسها، وحجم المصفوفة نفسه، والمترجم نفسه (MSVC 2019، مع الأعلام /O2 /arch:AVX2).\n\nإليكم الكود المبسط:\n\n#include \n#include \n#include \n#include \n\nint main() {\n const size_t N = 1'000'000;\n std::vector data(N, 0xFFFFFFFFFFFFFFFF); // جميع البتات = 1\n\n // الإصدار 1: عداد 32 بت\n unsigned int sum32 = 0;\n auto t1 = std::chrono::high_resolution_clock::now();\n for (unsigned int i = 0; i < data.size(); ++i) {\n sum32 += _mm_popcnt_u64(data[i]);\n }\n auto t2 = std::chrono::high_resolution_clock::n