Parallel.For 次迭代中的不同线程关联
Different thread affinities in 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。因此,要么 parallel.for 循环为它们使用单线程,要么一个设置也设置了其他迭代亲和力。另一个问题是,这是来自对延迟敏感的应用程序,所有这些关联设置都会增加 1 到 15 毫秒的延迟。
我必须显式使用线程吗?我应该只设置一次相关性吗?
编辑:我试过线程版本,同样的事情发生了。即使有明确的两个线程,都将 255 写入控制台。现在看来这个命令是针对进程而不是线程的。
OpenCL 上下文在 cpu 的一次迭代中使用最大内核执行内核。其他迭代使用 1-2 个内核来复制缓冲区并将命令发送到设备。当 opencl 使用 cpu 时,它会使用所有内核,并且设备无法获得足够的时间来复制缓冲区。我认为设备裂变似乎比解决这个问题更难。
Different thread affinities in Parallel.For Iterations
问题具有误导性,因为它基于 Parallel
API 表示多线程的假设。 Parallel
API 确实指的是数据并行处理,但不为调用提供任何保证 multiple threads
,尤其是对于上面提供的代码,每个线程几乎没有任何工作。
对于Parallel
API,可以设置Max degree of Parallelism,如下:
ParallelOptions parallelOption = new ParallelOptions();
parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount;
Parallel.For(0, 20, parallelOption, i =>
但这永远不能保证调用并行处理的线程数,因为线程是从 ThreadPool
开始使用的,而 CLR
在 运行 时间决定,基于要处理的工作量,是否需要处理超过 one thread
。
在同一个 Parallel
循环中,您可以尝试以下操作,打印 Thread.Current.ManageThreadId
,这将提供关于 Parallel
循环中调用的线程数的清晰思路。
Do I have to use threads explicitly and should I set affinities only once?
Edit: I tried threaded version, same thing happens. Even with explicit two threads, both writing 255 to console. Now it seems this command is for a process not a thread.
你能post多线程的代码吗,你能试试这样吗
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。
另一个注意事项,如您在上面的 link 中看到的,您可以根据处理器亲和力设置 hexadecimal
中的值,不确定值 254, 255
表示什么,做你真的有那么多处理器的服务器。
编辑:
尝试对您的程序进行以下编辑(基于正在打印两个线程 ID 的事实),现在当两个线程出现在图片中时,它们都获得相同的 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);
});
我需要一个并行 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。因此,要么 parallel.for 循环为它们使用单线程,要么一个设置也设置了其他迭代亲和力。另一个问题是,这是来自对延迟敏感的应用程序,所有这些关联设置都会增加 1 到 15 毫秒的延迟。
我必须显式使用线程吗?我应该只设置一次相关性吗?
编辑:我试过线程版本,同样的事情发生了。即使有明确的两个线程,都将 255 写入控制台。现在看来这个命令是针对进程而不是线程的。
OpenCL 上下文在 cpu 的一次迭代中使用最大内核执行内核。其他迭代使用 1-2 个内核来复制缓冲区并将命令发送到设备。当 opencl 使用 cpu 时,它会使用所有内核,并且设备无法获得足够的时间来复制缓冲区。我认为设备裂变似乎比解决这个问题更难。
Different thread affinities in Parallel.For Iterations
问题具有误导性,因为它基于 Parallel
API 表示多线程的假设。 Parallel
API 确实指的是数据并行处理,但不为调用提供任何保证 multiple threads
,尤其是对于上面提供的代码,每个线程几乎没有任何工作。
对于Parallel
API,可以设置Max degree of Parallelism,如下:
ParallelOptions parallelOption = new ParallelOptions();
parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount;
Parallel.For(0, 20, parallelOption, i =>
但这永远不能保证调用并行处理的线程数,因为线程是从 ThreadPool
开始使用的,而 CLR
在 运行 时间决定,基于要处理的工作量,是否需要处理超过 one thread
。
在同一个 Parallel
循环中,您可以尝试以下操作,打印 Thread.Current.ManageThreadId
,这将提供关于 Parallel
循环中调用的线程数的清晰思路。
Do I have to use threads explicitly and should I set affinities only once?
Edit: I tried threaded version, same thing happens. Even with explicit two threads, both writing 255 to console. Now it seems this command is for a process not a thread.
你能post多线程的代码吗,你能试试这样吗
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。
另一个注意事项,如您在上面的 link 中看到的,您可以根据处理器亲和力设置 hexadecimal
中的值,不确定值 254, 255
表示什么,做你真的有那么多处理器的服务器。
编辑:
尝试对您的程序进行以下编辑(基于正在打印两个线程 ID 的事实),现在当两个线程出现在图片中时,它们都获得相同的 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);
});