Различные сходства потоков в Parallel.For Iterations

Мне нужна итерация параллельного цикла for, чтобы использовать 7 ядер (или держаться подальше от 1 ядра), но другая итерация, чтобы использовать 8(все) ядер, и попробовал код ниже:

Parallel.For(0,2,i=>{
  if(i=0)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);

  if(i==1)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
  Thread.Sleep(25);// to make sure  both set their affinities
  Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});

это выдает 255 для обеих итераций. Таким образом, либо параллельный цикл использует для них один поток, либо один параметр устанавливает сходство других итераций. Другая проблема заключается в том, что это приложение, чувствительное к задержке, и все эти настройки сродства добавляют задержку от 1 до 15 миллисекунд.

Должен ли я использовать потоки явно, и я должен установить сходство только один раз?

Редактировать: я пробовал версию с резьбой, происходит то же самое. Даже с явными двумя потоками, оба записывают 255 в консоль. Теперь кажется, что эта команда предназначена для процесса, а не для потока.

В контексте OpenCL используется максимальное количество ядер для выполнения ядра на процессоре за одну итерацию. Другие итерации с использованием 1-2 ядер для копирования буферов и отправки команд на устройства. Когда процессор используется opencl, он использует все ядра, и устройства не могут получить достаточно времени для копирования буферов. Я думаю, что деление устройства сложнее, чем решить эту проблему.

1 ответ

Решение

Различные сходства потоков в Parallel.For Iterations

Вопрос вводит в заблуждение, так как основан на предположении, что Parallel API означает несколько потоков. Parallel API относится к параллельной обработке данных, но не дает никаких гарантий для вызова multiple threadsособенно для приведенного выше кода, где вряд ли есть работа на поток.

Для Parallel API, вы можете установить максимальную степень параллелизма следующим образом:

ParallelOptions parallelOption = new ParallelOptions();

parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount;

Parallel.For(0, 20, parallelOption, i =>

Но это никогда не гарантирует количество потоков, которые будут вызваны для параллельной обработки, поскольку потоки используются из ThreadPool а также CLR решает во время выполнения, основываясь на объеме работы, которая будет обработана, более чем one thread требуется для обработки.

В то же самое Parallel цикл вы можете попробовать следующее, распечатать Thread.Current.ManageThreadIdэто дало бы четкое представление о количестве потоков, вызываемых в Parallel петля.

Должен ли я использовать потоки явно, и я должен установить сходство только один раз?

Редактировать: я пробовал версию с резьбой, происходит то же самое. Даже с явными двумя потоками, оба записывают 255 в консоль. Теперь кажется, что эта команда предназначена для процесса, а не для потока.

Можете ли вы опубликовать код для нескольких потоков, вы можете попробовать что-то вроде этого.

Thread[] threadArray = new Thread[2];
threadArray[0] = new Thread(<ThreadDelegate>);
threadArray[1] = new Thread(<ThreadDelegate>);
threadArray[0]. ProcessorAffinity = <Set Processor Affinity>
threadArray[1]. ProcessorAffinity = <Set Processor Affinity>

Предполагая, что вы правильно назначили сходство, вы можете распечатать их и найти другие значения, проверьте следующее ProcessThread.ProcessorAffinity.

На другой ноте, как вы могли видеть по ссылке выше, вы можете установить значение в hexadecimal основанный на сродстве процессора, не уверен, что значения 254, 255 обозначает, у вас действительно есть сервер с таким количеством процессоров.

РЕДАКТИРОВАТЬ:

Попробуйте выполнить следующее редактирование вашей программы (основываясь на том факте, что печатаются два идентификатора нити), теперь к тому моменту, когда обе нити на картинке, они оба получают одинаковое значение variable iим нужен local variable чтобы избежать проблемы закрытия

Parallel.For(0,2,i=>{
  int local = i;
  if(local=0)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);

  if(local==1)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
  Thread.Sleep(25);// to make sure  both set their affinities
  Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});

РЕДАКТИРОВАТЬ 2: (в основном не работает, поскольку оба потока могут увеличиваться, до фактического выполнения логики)

 int local = -1;
  Parallel.For(0,2,i=>{
  Interlocked.Increment(ref local);
  if(local=0)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);

  if(local==1)
     Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
  Thread.Sleep(25);// to make sure  both set their affinities
  Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});
Другие вопросы по тегам