c - numa、mbind、段错误

标签 c linux numa

我已经使用 valloc 分配了内存,比方说 [15*sizeof(double)] 的数组 A。现在我将它分成三部分,我想将每一部分(长度为 5)绑定(bind)到三个 NUMA 节点(比方说 0、1 和 2)。目前,我正在做以下事情:

double* A=(double*)valloc(15*sizeof(double));

piece=5; 
nodemask=1;
mbind(&A[0],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);

nodemask=2;
mbind(&A[5],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);

nodemask=4;
mbind(&A[10],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);

第一个问题是我做得对吗? IE。例如,与页面大小正确对齐有什么问题吗?目前数组 A 的大小为 15,它运行良好,但如果我将数组大小重置为 6156000 和 piece=2052000,随后对 mbind 的三个调用以 &A[0]、&A[2052000] 和 &A[4104000 开头] 然后我遇到了段错误(有时它只是卡在那里)。为什么它运行小尺寸很好但大尺寸给我段错误?谢谢。

最佳答案

为此,您需要处理至少页面大小和页面对齐的内存块——在大多数系统中这意味着 4KB。在你的情况下,我怀疑页面被移动了两次(可能是三次),因为你调用了 mbind() 三次。

numa内存的定位方式是CPU socket 0的范围是0..X-1 MB,socket 1的范围是X..2X-1,socket 3的范围是2X-3X-1等等。当然,如果您在插槽 0 旁边放置一个 4GB 的内存条,在插槽 1 中放置一个 16GB 的内存条,那么分配是不均匀的。但原则仍然是,根据内存的实际位置,为每个套接字分配一大块内存。

由于内存的位置,您正在使用的内存的物理位置必须通过页面映射放置在线性(虚拟)地址空间中。

因此,对于大“ block ”的内存,移动它很好,但对于小块,它就不能很好地工作——你当然不能将一个页面“拆分”成仿射的东西两个不同的 CPU 插槽。

编辑:

要拆分数组,首先需要找到页面对齐的大小。

page_size = sysconf(_SC_PAGESIZE);

objs_per_page = page_size / sizeof(A[0]); 
// We should be an even number of "objects" per page. This checks that that 
// no object straddles a page-boundary
ASSERT(page_size % sizeof(A[0]));   

split_three = SIZE / 3; 

aligned_size = (split_three / objs_per_page) * objs_per_page;

remnant = SIZE - (aligned_size * 3);

piece = aligned_size;

mbind(&A[0],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);

mbind(&A[aligned_size],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);

mbind(&A[aligned_size*2 + remnant],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE);

很明显,您现在需要根据需要使用对齐的大小和剩余来类似地拆分三个线程。

关于c - numa、mbind、段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14528588/

相关文章:

c - 当 2 个程序映射同一个文件时,mmap 如何工作

c - 如何找出在C中存储一个值(int)需要多少字节

linux - Laravel 搞砸了 Homestead 权限

memory - 现代 Linux 中是否有 NUMA 下次接触策略

字符数组错误,需要一个表达式,错误

c - 如何在 C 中连接两个动态 int 数组?

python - python 中的 sudo renice

linux - 将 TCP 数据重定向到 ttyS0

linux -/sys/devices/system/node/node0/distance中的单位是什么

memory - 计算对内存的读写访问