لماذا لا يوجد الزائد متشابكة.إضافة يقبل يضاعف من المعلمات ؟
-
05-07-2019 - |
سؤال
أنا نقدر atomicity أن خيوط.متشابكة الدرجة يقدمها ؛ أنا لا أفهم ذلك ، لماذا إضافة وظيفة يقدم سوى اثنين الزائدة:واحد الاعداد الصحيحه, آخر يتوق.لماذا لا الزوجي ، أو أي نوع عددي لهذه المسألة ؟
ومن الواضح أن المقصود طريقة تغيير مزدوج هو CompareExchange;اعتقد هذا بسبب تعديل مزدوج هو عملية أكثر تعقيدا من تعديل عدد صحيح.لا يزال ليس واضحا لي لماذا إذا CompareExchange و إضافة على حد سواء يمكن قبول الأعداد الصحيحة ، فإنها لا يمكن أيضا قبول الزوجي.
المحلول
ويلتف الطبقة متشابكة حول وظائف ** متشابكة ويندوز API.
وهذه هي، في المقابل، التفاف حول API معالج الأصلي، وذلك باستخدام بادئة تعليمات LOCK ل x86. إلا يدعم التقديم التعليمات التالية:
<اقتباس فقرة>وBT، BTS، BTR، BTC، XCHG، XADD، إضافة، OR، ADC، SBB، AND، SUB، XOR، NOT، NEG، INC، ديسمبر
اقتباس فقرة>وعليك ملاحظة أن هذه، بدورها، الى حد كبير خريطة لطرق متشابكة. للأسف، لا يتم اعتماد وظائف أضف لأنواع غير صحيحة هنا. إضافة لصفقات الشراء 64BIT معتمد على منصات 64BIT.
وهنا كبيرة من المادة مناقشة دلالات قفل على مستوى تعليمات .
نصائح أخرى
وتناولت أخرى "لماذا؟". فمن السهل ولكن للفة Add(ref double, double)
الخاصة بك، وذلك باستخدام CompareExchange
بدائية:
public static double Add(ref double location1, double value)
{
double newCurrentValue = location1; // non-volatile read, so may be stale
while (true)
{
double currentValue = newCurrentValue;
double newValue = currentValue + value;
newCurrentValue = Interlocked.CompareExchange(ref location1, newValue, currentValue);
if (newCurrentValue == currentValue)
return newValue;
}
}
وCompareExchange
يحدد قيمة location1
أن newValue
، إذا كانت القيمة الحالية يساوي currentValue
. وهي إذ تفعل ذلك بطريقة الذرية، ذات ألوان، لا يمكننا الاعتماد عليه وحده دون اللجوء إلى الأقفال.
لماذا حلقة while (true)
؟ حلقات من هذا القبيل هي المعيار عند تنفيذ الخوارزميات المتزامنة بتفاؤل. سوف CompareExchange
لا تغيير location1
إذا كانت القيمة الحالية تختلف عن currentValue
. I تهيئة currentValue
إلى location1
- القيام قراءة غير المتطايرة (التي قد تكون قديمة، ولكن هذا لا يغير من صحة، وCompareExchange
سوف تحقق قيمة). إذا كانت القيمة الحالية (لا يزال) هو ما قد قرأنا من location
، سوف CompareExchange
تغيير القيمة إلى newValue
. إذا لم يكن كذلك، لدينا لإعادة محاولة CompareExchange
مع القيمة الحالية الجديدة، على النحو الذي عاد CompareExchange
.
إذا تم تغيير القيمة من خلال موضوع آخر حتى وقت لدينا CompareExchange
المقبل مرة أخرى، وسوف تفشل مرة أخرى، مما يستلزم إعادة المحاولة آخر - وهذا يمكن من الناحية النظرية أن تستمر إلى الأبد، وبالتالي الحلقة. إلا إذا كنت تتغير باستمرار قيمة من المواضيع متعددة، من المرجح أن يطلق CompareExchange
مرة واحدة فقط، إذا كانت القيمة الحالية لا تزال ما للقراءة غير المتطايرة من location1
أثمرت، أو مرتين، إذا كان مختلفا.
وكما قال ريد Copsey، خريطة عمليات متشابكة (عبر وظائف API Windows) لدعم تعليمات مباشرة من معالجات x86 / إلى x64. وبالنظر إلى أن واحدة من تلك الوظائف هو XCHG، يمكنك القيام بعملية XCHG الذرية دون الاهتمام حقا ما بت في الموقع المستهدف تمثل. وبعبارة أخرى، يمكن رمز "التظاهر" أن عدد النقطة العائمة 64 بت كنت تبادل هو في الواقع صحيح 64 بت، وسوف تعليمات XCHG لا يعرف الفرق. وهكذا، يمكن أن صافي توفير وظائف Interlocked.Exchange ليطفو والزوجي ب "التظاهر" بأنهم الأعداد الصحيحة والأعداد الصحيحة طويلة، على التوالي.
ولكن، كل من عمليات أخرى في الواقع لا تعمل على البتات الفردية من جهة، وهكذا لن تعمل إلا إذا القيم تمثل في الواقع صحيحة (أو صفائف بعض الشيء في بعض الحالات).
وأظن أن هناك نوعان من الأسباب.
- المعالجات المستهدفة .صافي الدعم متشابكة الزيادة فقط صحيح الأنواع.وأعتقد أن هذا هو قفل البادئة على x86, ربما تعليمات مماثلة موجودة المعالجات الأخرى.
- إضافة إلى النقطة العائمة عدد يمكن أن يؤدي في نفس العدد إذا كان كبيرا بما فيه الكفاية ، لذلك أنا لست متأكدا مما إذا كان يمكنك استدعاء هذا زيادة.ربما إطار المصممين يحاولون تجنب nonintuitive السلوك في هذه الحالة.