سؤال

تحتوي معالجات Intel 32 بت مثل Pentium على ناقل بيانات واسع 64 بت وبالتالي تجلب 8 بايت لكل وصول. بناءً على ذلك ، أفترض أن العناوين المادية التي تنبعث منها هذه المعالجات على ناقل العنوان هي دائمًا مضاعفات 8.

أولا ، هل هذا الاستنتاج صحيح؟

ثانياً ، إذا كان هذا صحيحًا ، فيجب على المرء محاذاة أعضاء هيكل البيانات على حدود 8 بايت. لكنني رأيت أشخاصًا يستخدمون محاذاة 4 بايت بدلاً من ذلك على هذه المعالجات.

كيف يمكن تبريرهم في القيام بذلك؟

هل كانت مفيدة؟

المحلول

القاعدة المعتادة المتمثلة في الإبهام (مباشرة من كتيبات التحسين في AMD) هي أنه يجب محاذاة كل نوع بيانات بحجمه. و int32 يجب محاذاة على حدود 32 بت ، int64 على حدود 64 بت ، وهلم جرا. سوف يتناسب char على ما يرام في أي مكان.

هناك قاعدة أخرى من الإبهام ، بالطبع "تم إخبار المترجم حول متطلبات المحاذاة". لا داعي للقلق بشأن ذلك لأن المترجم يعرف إضافة الحشوة والتعويضات الصحيحة للسماح بالوصول الفعال إلى البيانات.

الاستثناء الوحيد هو العمل مع تعليمات SIMD ، حيث يتعين عليك ضمان المحاذاة يدويًا على معظم المجمعين.

ثانياً ، إذا كان هذا صحيحًا ، فيجب على المرء محاذاة أعضاء هيكل البيانات على حدود 8 بايت. لكنني رأيت أشخاصًا يستخدمون محاذاة 4 بايت بدلاً من ذلك على هذه المعالجات.

لا أرى كيف يحدث هذا الفرق. يمكن لوحدة المعالجة المركزية ببساطة إصدار قراءة للكتلة 64 بت التي تحتوي على تلك البايتات الأربعة. هذا يعني أنه إما يحصل على 4 بايت إضافي قبل البيانات المطلوبة ، أو بعدها. ولكن في كلتا الحالتين ، يستغرق الأمر قراءة واحدة فقط. تضمن محاذاة 32 بت من البيانات على مستوى 32 بت أنها لن تعبر حدود 64 بت.

نصائح أخرى

الحافلة المادية بعرض 64 بت ... مضاعف 8 -> نعم

ومع ذلك ، هناك عاملان آخران في الاعتبار:

  1. بعض مجموعة تعليمات X86 معالجة بايت. بعضها محاذاة 32 بت (لهذا السبب لديك 4 بايت شيء). ولكن لا تعليمات (الأساسية) هي 64Bits محاذاة. يمكن لوحدة المعالجة المركزية التعامل مع الوصول إلى البيانات غير المحسوبة.
  2. إذا كنت تهتم بالأداء ، فيجب عليك التفكير في خط ذاكرة التخزين المؤقت ، وليس الذاكرة الرئيسية. خطوط ذاكرة التخزين المؤقت أوسع بكثير.

إنهم مبررون في القيام بذلك لأن التغيير إلى 8 بايت من شأنه أن يشكل تغييرًا في ABI ، وتحسين الأداء الهامشي لا يستحق المتاعب.

كما قال شخص آخر بالفعل ، تهم CACHELINES. جميع الوصول على ناقل الذاكرة الفعلي هي من حيث خطوط ذاكرة التخزين المؤقت (64 بايت على x86 ، IIRC). انظر "ما يحتاج كل مبرمج إلى معرفته عن الذاكرة" الذي تم ذكره بالفعل. وبالتالي فإن حركة الذاكرة الفعلية هي 64 بايت محاذاة.

للوصول العشوائي وطالما لم يتم تحديد البيانات (على سبيل المثال عبور الحدود) ، لا أعتقد أن الأمر مهم ؛ يمكن العثور على العنوان الصحيح والإزاحة في البيانات مع بناء بسيط وبناء في الأجهزة. يصبح بطيئًا عندما لا يكون الوصول إلى القراءة كافياً للحصول على قيمة واحدة. لهذا السبب عادةً ما يضع المجمعون قيمًا صغيرة (بايت وما إلى ذلك) معًا لأنهم لا يجب أن يكونوا في إزاحة محددة ؛ يجب أن تكون السراويل قصيرة على عناوين و 32 بت على عناوين 4 بايت و 64 بت على عناوين 8 بايت.

لاحظ أنه إذا كان لديك التخزين المؤقت للوصول إلى البيانات الخطية ، فستكون الأمور مختلفة.

حافلة 64 بت التي تشير إليها تغذية ذاكرة التخزين المؤقت. كوحدة المعالجة المركزية ، اقرأ دائمًا وتكتب خطوط ذاكرة التخزين المؤقت بالكامل. حجم خط ذاكرة التخزين المؤقت هو دائمًا مضاعف 8 ، ويتم محاذاة عنوانه المادي بالفعل عند 8 بايت إزاحة.

لا تستخدم عمليات نقل ذاكرة التخزين المؤقت إلى المسجلة قاعدة البيانات الخارجية ، وبالتالي فإن عرض تلك الحافلة غير ذي صلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top