Avatar ·

استبدال عداد الحلقة 32 بت بعداد 64 بت يسبب قفزات أداء غريبة مع _mm_popcnt_u64 على وحدات المعالجة المركزية Intel

```html مرحباً جميعاً! أنا أكتب دالة عالية الأداء لحساب البتات المفردة (popcount) في مصفوفة كبيرة من الأعداد الصحيحة 64-بت. أستخدم الدالة الداخلية `_mm_popcnt_u64` من SSE4.2. الكود بسيط — حلقة تقوم بجمع popcount لكل عنصر.\n\nلقد لاحظت سلوكاً غريباً: إذا قمت بتعريف متغير الحلقة كـ `uint32_t`، فإن الدالة تعمل بسرعة كبيرة. ولكن بمجرد استبداله بـ `uint64_t` (فقط بتغيير نوع `i`)، ينخفض الأداء إلى النصف تقريباً! لقد اختبرت على عدة معالجات Intel Core i7 (Sandy Bridge, Haswell, Skylake) — وظهر نفس التأثير. المترجم — MSVC 2010، رغم أن الوضع مشابه على GCC 4.6.3. التحسينات مفعلة (/O2 أو -O2).\n\nإليك مثال بسيط على الكود:\n\n```cpp\n#include \n#include \n#include \n#include \n\n// النسخة السريعة مع عداد 32-بت\nuint64_t popcnt32(const uint64_t* data, size_t size) {\n uint64_t result = 0;\n for (uint32_t i = 0; i < size; ++i) { // <-- 32-bit\n result += _mm_popcnt_u64(data[i ```