سؤال

هل Interlocked.Increment(ref x) أسرع أو أبطأ من x++ ل[إينتس] ويتوق على مختلف المنصات؟

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

المحلول

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

ويجب أن تستخدم Interlocked.Increment عندما تريد العمل ليكون الذري على الدولة التي يمكن أن تكون مشتركة بين المواضيع - انها لا يقصد به أن يكون بديلا كاملا ل x ++

نصائح أخرى

في تجربتنا في InterlockedIncrement () وآخرون على ويندوز هي تأثيرات كبيرة جدا. في حالة عينة واحدة تمكنا من القضاء على التعشيق واستخدام ++ / - بدلا من ذلك. هذا وحده خفض وقت التشغيل من 140 ثانية إلى 110 ثانية. تحليلي هو أن التعشيق قوات إيابا الذاكرة (وإلا كيف يمكن أن النوى الأخرى ترى ذلك؟). مخبأ L1 القراءة / الكتابة حوالي 10 دورات على مدار الساعة، ولكن ذاكرة القراءة / الكتابة أشبه 100.

في هذه الحالة عينة، ويقدر عدد عمليات زيادة / إنقاص بنحو 1000000000. حتى على ذكر 2GHz CPU وهذا هو شيء من هذا القبيل 5 ثوان ل++ / -، و 50 ثانية لالتعشيق. انتشرت الفرق عبر العديد من المواضيع، وعلى مقربة لمدة 30 ثانية.

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

ولكن، وكما ترون من خلال اختبار لنفسك، وعدم تنفيذ نفسه.

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

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

وسيكون دائما أبطأ لأنه يحتوي على أداء قفل وحدة المعالجة المركزية للحافلات مقابل مجرد تحديث سجل. ومع ذلك وحدات المعالجة المركزية الحديثة على تحقيق أداء السجل القريب حتى انها لا تذكر حتى في الوقت الحقيقي تجهيز.

وبلدي برفومنس اختبار:

ومتقلبة: 65174400

وقفل: 62428600

ومتشابكة: 113248900

TimeSpan span = TimeSpan.FromSeconds(5);

object syncRoot = new object();
long test = long.MinValue;

Do(span, "volatile", () => {

    long r = Thread.VolatileRead(ref test);

    r++;

    Thread.VolatileWrite(ref test, r);
});

Do(span, "lock", () =>
{
    lock (syncRoot)
    {
        test++;
    }
});

Do(span, "interlocked", () =>
{
    Interlocked.Increment(ref test);
});
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top