سؤال

ما هو الفرق بين الانحياز محاذاتها ذاكرة الوصول ؟

أنا أعمل على TMS320C64x DSP, و أريد أن استخدام الدالات المضمنة (ج وظائف تعليمات التجميع) وقد

ushort & _amem2(void *ptr);
ushort & _mem2(void *ptr);

حيث _amem2 لا الانحياز الوصول من 2 بايت ، _mem2 لا محاذاتها الوصول.

متى يجب أن أستخدم ؟

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

المحلول

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

المترجم C يضع دائما المتغيرات التي تقوم بتعريف في عناوين التي تلبي محاذاة "الصحيحة". حتى إذا PTR نقطة لمثل متغير uint16_t، سيتم محاذاة ذلك، ويمكنك استخدام _amem2. تحتاج إلى استخدام _mem2 فقط إذا كنت الوصول إلى مثل صفيف بايت معبأة تلقت عبر I / O، أو بايت في منتصف السلسلة.

نصائح أخرى

والعديد من أبنية الكمبيوتر ذاكرة تخزين في "كلمات" من عدة بايت لكل منهما. على سبيل المثال، 32 بت معمارية إنتل بتخزين كلمات 32 بت، كل من 4 بايت. يتم تناول الذاكرة مستوى بايت واحد، ولكن؛ لذا عنوان يمكن "الانحياز"، وهذا يعني أن تبدأ في كلمة الحدود، أو "محاذاتها"، وهذا يعني أنه لا يفعل ذلك.

في بعض أبنية عمليات الذاكرة معينة قد يكون أبطأ أو حتى تماما لا يسمح على العناوين الصغيرة المحايدة.

وهكذا، إذا كنت تعرف يتم محاذاة العناوين على العناوين الصحيحة، يمكنك استخدام _amem2 ()، للسرعة. خلاف ذلك، يجب عليك استخدام _mem2 ().

الانحياز عناوين هي تلك التي هي مضاعفات الوصول الحجم في السؤال.

  • وصول 4 بايت الكلمات في عناوين متعددة من 4 سوف تكون محاذاة
  • وصول 4 بايت من العنوان (أقول) 3 يكون محاذاتها الوصول

فمن المحتمل جدا أن _mem2 وظيفة والتي سوف تعمل أيضا على محاذاتها يصل سوف يكون أقل الأمثل للحصول على الصحيح التحالفات العمل في مدونة.وهذا يعني أن _mem2 وظيفة من المرجح أن تكون أكثر تكلفة ثم _amem2 الإصدار.

لذا عندما تحتاج الأداء (خاصة عندما تعلم أن زمن الوصول إلى عالية) أنه سيكون من الحكمة أن تحديد متى يمكنك استخدام الانحياز الوصول.على _amem2 موجود لهذا الغرض -- لتعطيك الأداء عندما كنت تعرف الوصول الانحياز.

عندما يتعلق الأمر إلى 2 بايت يصل إلى تحديد محاذاة عمليات بسيطة جدا.
إذا كان كل الوصول إلى عناوين العملية 'حتى' (وهذا هو ، LSB صفر) ، لديك 2 بايت محاذاة.هذا يمكن التحقق بسهولة ،

if (address & 1) // is true
    /* we have an odd address; not aligned */
else
    /* we have an even address; its aligned to 2-bytes */

وأعرف أن هذا هو السؤال القديم مع الجواب المحدد ولكن لم أرى أي شخص شرح الجواب على ما هو الفرق بين ذاكرة الوصول الانحياز ومحاذاتها ...

وسواء كان ذلك الدرهم أو SRAM أو فلاش أو غيرها. خذ SRAM كمثال بسيط أنها بنيت من بت سيتم بناء SRAM محددة من عدد محدد من بت واسعة وعدد محدد من الصفوف عميقة. يتيح القول 32 بت واسعة والعديد من / العديد من الصفوف العميق.

وإذا كنت تفعل كتابة 32 بت لمعالجة 0x0000 في هذا SRAM، وحدة تحكم الذاكرة حول هذا SRAM يمكن القيام به مجرد دورة الكتابة واحدة إلى الصف 0.

وإذا كنت تفعل كتابة 32 بت لمعالجة 0x0001 في هذا SRAM، على افتراض أن يسمح، وحدة تحكم تحتاج إلى القيام قراءة الصف 0، تعديل ثلاث وحدات البايت، والحفاظ على واحد، وكتابة ذلك إلى صف 0، ثم قرأ الصف 1 تعديل بايت واحد وترك الثلاثة الأخرى كما وجدت والكتابة أن يعود. التي بايت الحصول على تعديلها أو ليس لديها علاقة مع endianness للنظام.

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

إذا كان لي أن أقرأ 32 بت من عنوان 0x0000 ثم قراءة واحدة الصف 0، القيام به. ولكن قراءة من 0x0001 ولدي للقيام اثنين من يقرأ row0 وROW1 واعتمادا على تصميم نظام لمجرد ارسال هذه البتات 64 إلى المعالج ربما الساعات حافلة اثنين بدلا من واحدة. أو وحدة تحكم الذاكرة لديه منطق إضافية بحيث يتم محاذاة 32 بت على ناقل البيانات في دورة حافلة واحدة.

ويقرأ 16 بت هي أفضل قليلا، وقراءة من 0x0000، 0x0001 و0x0002 سيكون فقط للقراءة من row0 ويمكن أن تقوم على تصميم النظام / معالج إرسال هذه البتات 32 ذهابا والمعالج مقتطفات منها أو تحول لهم في تحكم في الذاكرة بحيث تهبط على الممرات بايت معينة بحيث المعالج لا يضطر تدوير حولها. واحدة أو أخرى أن لم يكن على حد سواء. A القراءة من 0x0003 على الرغم من هو مثل أعلى لديك لقراءة التوالي 0 وROW1 باعتبارها واحدة من وحدات البايت الخاصة بك في كل وثم إما إرسال 64 بت يعود للمعالج لاستخراج أو وحدة تحكم الذاكرة يجمع بين البتات في الاستجابة حافلة واحدة 32 بت ( على افتراض الحافلة بين وحدة تحكم المعالج والذاكرة هو 32 بت واسعة لهذه الأمثلة).

ووالكتابة 16 بت على الرغم ينتهي دائما مع واحد على الأقل للقراءة تعديل والكتابة في هذا المثال SRAM، عنوان 0x0000، 0x0001 و0x0002 قراءة row0 تعديل اثنين بايت والكتابة مرة أخرى. عنوان 0x0003 قراءة صفين تعديل بايت واحد كل والكتابة مرة أخرى.

و8 بت تحتاج فقط إلى قراءة صف واحد التي تحتوي على تلك بايت، يكتب على الرغم من هي قراءة تعديل والكتابة من صف واحد.

وديدنت ARMV4 مثل محاذاتها على الرغم من أنك يمكن تعطيل فخ ونتيجة ليست مثل تتوقعون أعلاه، تسمح يست مهمة، والأسلحة الحالية محاذاتها وتعطيك سلوك أعلاه يمكنك تغيير بعض الشيء في سجل السيطرة وبعد ذلك سيتم إحباط نقل الصغيرة المحايدة. تستخدم MIPS عدم السماح، ولست متأكدا ما يفعلونه الآن. x86 و 68K وغيرها، وسمح وتحكم في الذاكرة وربما كان للقيام معظم العمل.

والتصاميم التي لا أميل تسمح بذلك بشكل واضح عن أداء وأقل المنطق في ما يقول البعض يشكل عبئا على المبرمجين الآخرين قد أقول أنه أي عمل إضافي على مبرمج أو أسهل على مبرمج. محاذاة أو لا يمكنك أن ترى أيضا لماذا يمكن أن يكون أفضل أن لا محاولة لإنقاذ أي ذاكرة بجعل 8 المتغيرات قليلا ولكن المضي قدما وحرق كلمة 32 بت أو مهما كان حجم الطبيعي للتسجيل أو الأتوبيس. وقد يكون من المفيد أدائك بتكلفة صغيرة من بعض بايت. ناهيك عن رمز إضافية سوف تحتاج إلى مترجم لإضافة لجعل دعنا نقول 32 بت تسجيل تقليد متغير 8 بت، اخفاء وتوقيع أحيانا التمديد. حيث استخدام أحجام الأم السجل ليس مطلوبا من هذه التعليمات إضافية. يمكنك أيضا حزمة أشياء متعددة في / ذاكرة مكان الحافلة واسعة والقيام دورة ذاكرة واحدة لجمع أو اكتبها ثم استخدام بعض تعليمات إضافية إلى manipulate بين السجلات لا يكلف الكبش وغسل محتمل على عدد من التعليمات.

وأنا لا أوافق على أن المجمع سوف محاذاة دائما الحق البيانات لهدف، وهناك طرق لكسر ذلك. وإذا كان الهدف دويسنت دعم محاذاتها سوف تصل الخطأ. أن المبرمجين تحتاج أبدا للحديث عن هذا إذا كان المترجم دائما أنها لم تستند على حق أي مدونة قانونية يمكن أن نخرج، لن يكون هناك أي سبب لهذا السؤال إلا إذا كان للأداء. إذا كنت لا تسيطر على عنوان الفراغ PTR إلى محاذاة أو لا ثم لديك لاستخدام mem2 () وصول محاذاتها في كل وقت أو لديك للقيام إذا، ثم بين آخر في التعليمات البرمجية الخاصة بك على أساس قيمة PTR كما نيك أشار. بإعلان الفراغ كما المترجم C لديها الآن أي وسيلة للتعامل بشكل صحيح مع محاذاة وذلك لن يكون مضمونا. إذا كنت تأخذ شار * فريق اعادة الاعمار وذلك لتغذية هذه المهام كل الرهانات على المترجم الحصول على ذلك الحق دون أن إضافة رمز إضافي دفن إما في وظيفة mem2 () أو خارج هاتين الوظيفتين. حتى كما هو مكتوب في mem2 سؤالك () هي الإجابة الصحيحة فقط.

وDRAM يقول المستخدمة في سطح المكتب / الكمبيوتر المحمول يميل إلى أن يكون 64 أو 72 (مع رعاية الطفولة المبكرة) بت واسعة، ويتم محاذاة كل الوصول إليها. على الرغم من أن تتم العصي الذاكرة فعليا حتى من عرضه 8 بت أو 16 أو 32 بت واسعة رقائق البطاطس. (هذا قد يتغير مع الهواتف / أقراص لأسباب مختلفة) وحدة تحكم الذاكرة ومثالي مخبأ واحد على الأقل يجلس أمام هذه درهم بحيث المداخل الصغيرة المحايدة أو حتى الانحياز التي هي أصغر من عرض حافلة للقراءة تعديل-يكتب يتم التعامل مع SRAM في مخبأ وهي طريقة أسرع، ويتم محاذاة كل المداخل درهم عرض حافلة مليئة يصل. إذا كان لديك أي مخبأ أمام درهم وتم تصميم جهاز تحكم عن عرض كامل يصل بعد ذلك هو أسوأ أداء، إذا صممت لتضيء الممرات بايت على حدة (على افتراض رقائق واسعة 8 بت) ثم لم يكن لديك للقراءة تعديل -writes لكن وحدة تحكم أكثر تعقيدا. إذا كانت حالة الاستخدام الأمثل لمع ذاكرة التخزين المؤقت (إذا كان هناك واحد في التصميم) ثم أنه قد لا يكون من المنطقي أن يكون هذا العمل الإضافي في وحدة تحكم عن كل حارة بايت، ولكن يكون ذلك فقط تعرف كيف تفعل نقل العرض حافلة كاملة الحجم أو مضاعفات.

و_mem2 هو أكثر عمومية. انه سوف يعمل إذا كان الانحياز PTR أم لا. _amem2 هو أكثر صرامة: أنه يتطلب أن تكون محاذاة PTR (على الرغم من المفترض أكثر قليلا فعالة). وذلك باستخدام _mem2 إلا إذا كنت تستطيع أن تضمن أن PTR يتم محاذاة دائما.

والعديد من المعالجات لها قيود التوافق على الوصول إلى الذاكرة. وصول محاذاتها إما يولد مقاطعة استثناء (على سبيل المثال ARM)، أو هو مجرد أبطأ (على سبيل المثال إلى x86).

وربما يتم تنفيذ _mem2 كما جلب اثنين بايت واستخدام عمليات التحول وأو أحادي المعامل لجعل 16 بت USHORT للخروج منها.

و_amem2 ربما فقط يقرأ USHORT 16-بت من PTR محددة.

وأنا لا أعرف على وجه التحديد TMS320C64x ولكن كنت اعتقد انه يتطلب المواءمة 16 بت ليصل إلى الذاكرة 16 بت. بحيث يمكنك استخدام _mem2 دائما ولكن مع عقوبة الأداء، و_amem2 عند يمكن أن تضمن أن PTR، بل هو عنوان.

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