سؤال

هل هناك دعم مدمج في TPL (مكتبة تابعة للمهمة) لعمليات التجديد؟

كنت ألعب مؤخرًا مع روتين لتنفيذ استبدال الشخصية على صفيف حرف باستخدام جدول بحث أي ترجمة:

for (int i = 0; i < chars.Length; i++)
{
    char replaceChar;

    if (lookup.TryGetValue(chars[i], out replaceChar))
    {
        chars[i] = replaceChar;
    }
}

استطعت أن أرى أن هذا يمكن أن يكون موازيًا تافهة ، لذلك قفز مع طعنة أولى عرفت أنها ستعمل أسوأ لأن المهام كانت جيدة جدًا:

Parallel.For(0, chars.Length, i =>
{
    char replaceChar;

    if (lookup.TryGetValue(chars[i], out replaceChar))
    {
        chars[i] = replaceChar;
    }
});

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

أنا متأكد من أنه يجب أن يكون هناك دعم مدمج للتثبيت في TPL. ما هو بناء الجملة ، وكيف يمكنني استخدامه؟

const int CharBatch = 100;
int charLen = chars.Length;

Parallel.For(0, ((charLen / CharBatch) + 1), i =>
{
    int batchUpper = ((i + 1) * CharBatch);

    for (int j = i * CharBatch; j < batchUpper && j < charLen; j++)
    {
        char replaceChar;

        if (lookup.TryGetValue(chars[j], out replaceChar))
        {
            chars[j] = replaceChar;
        }
    }
});

تحديث

بعد استخدام إجابة @أوليفر واستبدالها Parallel.For مع الموازي. foreach و partitioner رمز على النحو التالي:

const int CharBatch = 100;

Parallel.ForEach(Partitioner.Create(0, chars.Length, CharBatch), range =>
{
    for (int i = range.Item1; i < range.Item2; i++)
    {
        char replaceChar;

        if (lookup.TryGetValue(chars[i], out replaceChar))
        {
            chars[i] = replaceChar;
        }
    }
});
هل كانت مفيدة؟

المحلول

من الأفضل الحصول على رأسك من حولك يجب أن تحصل على أنماط للبرمجة الموازية: فهم وتطبيق أنماط متوازية مع .NET Framework 4. إنه مصدر رائع ويشرح الطرق المشتركة حول كيفية استخدام TPL.

ألقِ نظرة على الصفحة 26 (أجسام حلقة صغيرة جدًا). ستجد هذا المثال:

Parallel.ForEach(Partitioner.Create(from, to), range =>
{
    for (int i = range.Item1; i < range.Item2; i++)
    {
        // ... process i
    }
});

لذا فإن القطعة المفقودة التي تبحث عنها هي System.Concurrent.Collections.Partitioner.

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