سؤال

هل هناك حاجة للقلق بشأن MemoryBarriers عند استخدام الامتدادات المتوازية؟

تحرير - للتوضيح حيث أن السؤال الأصلي كان مفتوحًا:(إجابة @ xanatos كانت هي التي كنت أبحث عنها)

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

class Program
{
  static void Main(string[] args)
  {
    var t = new Test();
    t.InitializePropertiesInParallel();
    var a = t.PropA; // Could never be 0?
    var b = t.PropB; // Could never be 0?
  }
}

public class Test
{
  public int PropA { get; set; }
  public int PropB { get; set; }

  public void InitializePropertiesInParallel()
  {
    var initializers = new List<Action<int>>()
    {
      i => PropA = i,
      i => PropB = i
    };

    initializers.AsParallel().ForAll(a => a(1));
  }
}
هل كانت مفيدة؟

المحلول

إذا لم يكن كل عامل بحاجة إلى البيانات التي أعدها العمال الآخرون (لذلك لا يوجد أي موقف حيث يكتب العامل 1 A ويقرأ العامل 2 A) ليست هناك حاجة لـ MemoryBarrier.عندما تنتهي جميع المهام هناك Wait الذي يعمل بمثابة MemoryBarrier (في النهاية، حتى لو لم تراه، يوجد في مكان ما بنية مزامنة تنتظر انتهاء جميع العمال)

نصائح أخرى

تبقي شيئا واحدا في الاعتبار هنا: إبطال خط ذاكرة التخزين المؤقت.إنه موضوع معقد، ولكن هناك مقالة MSDN رائعة هنا .

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

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

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