2016-09-16 12 views
0

мне нужна итерация параллельного цикла для использования 7 ядер (или остаться в стороне от 1 ядра), но другая итерация использовать 8 (все) ядра и попытался код ниже:Различных нити сродство в Parallel.For Итерациях

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 для обеих итераций. Таким образом, либо цикл parallel.for использует для них один поток, либо один параметр устанавливает итеративность других итераций. Еще одна проблема заключается в том, что это приложение, чувствительное к задержкам, и все эти настройки сродства добавляют задержку от 1 до 15 миллисекунд.

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

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

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

+0

Я не знаю достаточно, чтобы помочь здесь, но Parallel.For использует потоки или пул задач? Потому что я видел, как он создавал и разрушал степени параллелизма на основе запроса пула задач. Я довольно уверен, что потоки не делают этого. У меня было maxDegree, установленное на 26 операционных сравнениях в 3,2 миллиарда, а активные нити колебались бы между 5 и 26 за шесть дней, которые потребовались для завершения. Поэтому, хотя я не могу помочь, меня определенно интересует ваш вопрос. –

+0

Я не мог найти ничего подобного minParallelismDegree для этого, но я пытаюсь использовать чистые потоки, используя анонимный делегат функции и обработчик событий. –

+0

Это параметр, который вы устанавливаете в Parallel.For - https://msdn.microsoft.com/en-us/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism(v=vs.110).aspx, как я уже сказал, я «Невежественный, но это может помочь вам понять материал под капотом. –

ответ

2

другой поток сродством в Parallel.For Итерации

Вопрос вводит в заблуждение, так как он основан на предположении, что 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, действительно ли у вас есть сервер с таким количеством процессоров.

EDIT:

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

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); 
}); 

EDIT 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); 
}); 
+0

Для первой части требуется от 20 до 200 миллисекунд на итерацию, которая балансирует нагрузку и балансирует работу со всеми устройствами и делает их равной латентностью. –

+0

--------------- Thread.Current.ManageThreadId 10 Thread.Current.ManageThreadId 16 --------------- его вроде этого, но только второй изменяется –

+0

Проверьте, если это происходит, то в основном это проблема закрытия, так как к тому моменту, когда оба потока приходят на изображение, значение i равно 0 для обоих из них –