Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在Windows 10上通过openMP使用所有NUMA节点_C_Windows_Openmp_Affinity_Numa - Fatal编程技术网

C 如何在Windows 10上通过openMP使用所有NUMA节点

C 如何在Windows 10上通过openMP使用所有NUMA节点,c,windows,openmp,affinity,numa,C,Windows,Openmp,Affinity,Numa,我可以访问由两个NUMA节点组成的双套接字系统来进行一些数据处理 我的代码相对简单,我将openMP用于一个主要的可并行循环,如下所示(k是一个函数参数,buffer是一个长度为n的千兆字节数组): uint64\u t m=0; uint64_t*rk=(uint64_t*)calloc(k,sizeof(uint64_t)); #pragma-omp并行 { #pragma omp表示缩减(+:m),缩减(+:rk[:k]) 对于(uint64_t i=0;i我找到了问题的原因。计算机上有超

我可以访问由两个NUMA节点组成的双套接字系统来进行一些数据处理

我的代码相对简单,我将openMP用于一个主要的可并行循环,如下所示(k是一个函数参数,buffer是一个长度为n的千兆字节数组):

uint64\u t m=0;
uint64_t*rk=(uint64_t*)calloc(k,sizeof(uint64_t));
#pragma-omp并行
{
#pragma omp表示缩减(+:m),缩减(+:rk[:k])

对于(uint64_t i=0;i我找到了问题的原因。计算机上有超过64个逻辑核,因此Windows需要两个CPU组来寻址。默认情况下,它将每个NUMA节点放在自己的组中

修复方法是,如果物理内核少于64个,则禁用HTT,或者在bios中禁用NUMA分组。在后一种情况下,前64个逻辑内核将分组并在Windows中显示为单个NUMA节点,其余的放在第二个节点中。理想的解决方案将取决于您的特定应用程序,无论您是否从使用所有磁芯或超读中获益

[编辑]
您也可以手动管理线程。如果您想这样做,我建议深入研究
Processtopologyapi.h
processthreadsapi.h
,特别是函数
GetActiveProcessorCount
SetThreadGroupAffinity
,您在Windows上使用的编译器是什么?我使用了gcc和mingw的gcc(x86_64-w64-mingw32-gcc),都在Cygwin下。结果是一样的。我刚刚在命令行(cl)中使用Visual Studio 2017编译器进行了尝试我也有同样的问题。下一步我会尝试使用英特尔编译器,但我很悲观。英特尔编译器使用了所有现成的逻辑核!尽管在我的例子中,我最终坚持使用gcc并手动将线程分配给CPU组。我将研究hwloc,使其更具可移植性。
uint64_t m=0;
uint64_t *rk = (uint64_t *) calloc(k, sizeof(uint64_t));
#pragma omp parallel
{
    #pragma omp for reduction(+:m), reduction(+:rk[:k])
    for (uint64_t i=0; i<n-k; i++)
    {
        m += (uint64_t)buffer[i];
        for (uint64_t j=0; j<k; j++)
        {
            rk[j] += (uint64_t)buffer[i]*(uint64_t)buffer[i+j];
        }
    }
    /* Other stuff, serial and parallel */
}