لا وجود مزامنة تساعد على التخلص من الطيارة مفتاح الكلمة ؟

StackOverflow https://stackoverflow.com/questions/1616093

سؤال

لدي متعددة R/W قفل الطبقة التي تحافظ على القراءة والكتابة في انتظار قراءة ريثما أكتب العدادات.مزامنة الحراس لهم من خيوط متعددة.

سؤالي هو: هل ما زلنا بحاجة العدادات إلى أن أعلن عن وتقلب حتى أن المترجم لن تفسدها أثناء القيام الأمثل.

أم أن المترجم يأخذ في الاعتبار أن العدادات حراسة مزامنة.

أنا أفهم أن مزامنة هو وقت تشغيل آلية التزامن و "المتقلبة" الكلمة هو وقت الترجمة إشارة إلى المترجم أن تفعل الشيء الصحيح أثناء القيام التحسينات.

التحيات ، -جاي.

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

المحلول

هناك 2 في الأساس لا علاقة لها البنود هنا دائما الخلط.

  • متقلبة
  • المواضيع, أقفال الذاكرة الحواجز ، إلخ.

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

الذاكرة الحواجز (التي قدمتها mutexes, أقفال ، الخ) ، كما نقلت من عشب سوتر في جواب آخر ، هي من أجل منع وحدة المعالجة المركزية من إعادة ترتيب قراءة/كتابة طلبات الذاكرة بغض النظر عن المترجم قال أن تفعل ذلك.أي لا تحسين ، لا تأخذ مختصرة - على مستوى وحدة المعالجة المركزية.

مماثلة, ولكن في الواقع أشياء مختلفة جدا.

في قضيتك و في معظم الحالات من تأمين سبب متقلبة ليس من الضروري ، بسبب وظيفة المكالمات تبذل من أجل تأمين.أي:

وظيفة طبيعية المكالمات التي تؤثر على التحسينات:

external void library_func(); // from some external library

global int x;

int f()
{
   x = 2;
   library_func();
   return x; // x is reloaded because it may have changed
}

إلا إذا كان المترجم يمكن دراسة library_func() و تحديد أنه لا touch x, فإنه سيتم إعادة قراءة x على العودة.هذا هو حتى من دون المتقلبة.

خيوط:

int f(SomeObject & obj)
{
   int temp1;
   int temp2;
   int temp3;

   int temp1 = obj.x;

   lock(obj.mutex); // really should use RAII
      temp2 = obj.x;
      temp3 = obj.x;
   unlock(obj.mutex);

   return temp;
}

بعد قراءة الكائنات.x temp1, المترجم هو الذهاب إلى إعادة قراءة الكائنات.x temp2 - ليس لأن السحر من الأقفال - ولكن لأنه غير متأكد ما إذا كان القفل() تعديل الكائنات.ربما يمكن تعيين مترجم أعلام بقوة الأمثل (أي مستعار ، الخ) وبالتالي لا إعادة قراءة x, ولكن بعد ذلك مجموعة من التعليمات البرمجية الخاصة بك سيكون على الأرجح بداية الفشل.

بالنسبة temp3, المترجم (أمل) لا إعادة قراءة الكائنات.x.إذا كان لسبب الكائنات.× يمكن أن يتغير بين temp2 و temp3, ثم يمكنك استخدام متغير (و القفل الخاص بك سوف تكون مكسورة/عديمة الفائدة).

وأخيرا ، إذا قفل()/فتح() الوظائف بطريقة أو بأخرى inlined ربما المترجم أن تقيم رمز نرى أن الكائنات.x لا يتغير.ولكن أنا أضمن أحد أمرين هنا:- مضمنة رمز في نهاية المطاف يدعو بعض مستوى نظام التشغيل قفل وظيفة (وبالتالي منع التقييم) أو - استدعاء بعض asm حاجز الذاكرة تعليمات (أي التي هي ملفوفة في وظائف مضمنة مثل __InterlockedCompareExchange) أن المترجم الخاص بك سوف تعترف وبالتالي تجنب إعادة ترتيب.

تحرير:P. S.نسيت أن أذكر - على pthreads الأشياء بعض المجمعين تحمل علامة "POSIX متوافقة" مما يعني ، من بين أمور أخرى, أنها سوف تعترف pthread_ وظائف و لا سيئة أمثل من حولهم.أي على الرغم من C++ القياسية لا أذكر المواضيع بعد هذين المجمعين لا (على الأقل الحد الأدنى).

لذا الجواب القصير

أنت لا تحتاج إلى متقلبة.

نصائح أخرى

من عشب ساتر المادة "استخدام المقاطع الحرجة (ويفضل أقفال) للقضاء على سباقات" (http://www.ddj.com/cpp/201804238):

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

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

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

يستخدم

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

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

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

والاحتفاظ بها متقلبة.

في حين أن هذا قد تعتمد على خيوط مكتبة تستخدمه أفهمه هو أن أي لائقة مكتبة لا تتطلب استخدام volatile.

في Pthreads, على سبيل المثال, استخدام مزامنة سوف تضمن أن يحصل على البيانات الخاصة بك ملتزمة الذاكرة بشكل صحيح.

تحرير: أنا هنا تأييد توني الجواب باعتبارها أفضل من بلدي.

وكنت لا تزال بحاجة إلى "متقلبة" الكلمة.

ووكائنات المزامنة تمنع العدادات من الوصول المتزامن.

و"متقلبة" يقول المترجم لاستخدامها في الواقع وصفة طبية بدلا من التخزين المؤقت قبل أن تتحول إلى تسجيل CPU (والذي لن يتم تحديثها بواسطة موضوع المتزامنة).

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