Различные сходства потоков в 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);
});