2010-10-20 3 views
5

Я хочу преобразовать цикл for, который увеличивает итератор на 2 каждый проход в цикл Parallel For, используя TPL. Данные никоим образом не зависят от заказа или ограничений, но я хочу обрабатывать данные только в каждом другом элементе моего исходного массива (который является _Datalist в коде ниже), следовательно, необходимо увеличить его на 2.Изменение инкрементного значения цикла C# Parallel.For

Мой цикл по:

for (int i = 1; i < _DataList.Length - 1; i += 2) 
{ 
    // Do work for _DataList[i] 
} 

можно ли сказать, параллельный цикл, что я хочу, чтобы увеличить I на два, а не один?

Вот параллельный цикл, но, очевидно, я это увеличивающийся только 1 каждая итерация:

 Task.Factory.StartNew(() => 
      Parallel.For(1, _DataList.Length, i => 
      { 
       // do work for _DataList[i]      
      }) 
     ); 

Я мог бы сказать, тело внутреннего цикла игнорировать нечетные значения I, но кажется, что Лил грязным - есть способ сделать это в инициализации цикла каким-то образом?

+2

Не просто игнорировать нечетные значения; что создает в два раза больше задач, чем вам нужно, что добавляет много лишних накладных расходов. – Gabe

+0

Да, я понимаю, что вы имеете в виду – Gareth

ответ

10

Как насчет:

var odds = Enumerable.Range(1, _DataList.Length).Where(i => i % 2 != 0); 

Task.Factory.StartNew(() => 
    Parallel.ForEach(odds, i => 
    { 
     // do work for _DataList[i]      
    }) 
); 
+0

У вас хорошая репутация по какой-то причине –

+0

aha, мне нравится ваше мышление. Благодарю. – Gareth

10

Вы можете вдвое сократить количество шагов и удвоить показатели:

Parallel.For(0, _DataList.Length/2, i => 
{ 
    // do work for _DataList[2 * i]      
}); 
0

Darin Dimitrov's answer показывает простой способ для достижения этой цели.

Однако это не было добавлено, так как это, как правило, знак того, что тела петли не являются действительно различными. В большинстве случаев необходимость использования другого значения прироста обычно возникает только при необходимости обработки в определенном порядке или других проблем, которые могут привести к распараллеливанию для создания условий гонки.

+0

Отмечено для использования в будущем, но в том случае, когда я применяю этот цикл, порядок обработки элементов действительно не является проблемой – Gareth

+0

@Gareth: Я просто упоминаю об этом, поскольку на самом деле было обсуждение (которое я не могу найти atm) Стивена Туба, в котором особо упоминается, почему Parallel.For не добавлял эту функцию - и она в основном сводилась к ней, как правило, это проблематично для параллельной обработки, но вы всегда можете обойти ее через разделитель или parallel.foreach. –

+0

Я считаю, что этот случай использования возникает очень естественно при работе с SIMD-инструкциями в .NET, поскольку они работают путем создания 'Vector <'T>' для каждого n-го элемента массива, где N - ширина вектора. Вы не можете использовать Parallel.For для маленьких векторизованных функций, потому что перечислители или умножительные трюки наносят ущерб преимуществу. – jackmott

-1

Просто пропустите четные значения.

Task.Factory.StartNew(() => 
       Parallel.For(1, _DataList.Length, i => 
       { 
        if(i % 2 == 0) 
        { 
         // do work for 
        } 
       }) 
      ); 
+1

Не могли бы вы подробнее рассказать о своем ответе? Обычно считается хорошей практикой давать некоторую информацию или объяснение ответов, которые вы даете. Это может помочь будущим пользователям или OP больше. – Bono

+0

Я «юниор», я не знаю, что делаю! :) – Junior

+0

Это не очень хорошая идея, поскольку вы создаете накладные расходы и пытаетесь избежать - см. Первый комментарий к вопросу. К счастью, были хорошие решения 5 лет назад :) – Gareth

Смежные вопросы