numa,mbind,segfault

我已经使用valloc分配内存,比方说[15 * sizeof(double)]的数组A. 现在我把它分成三块,我想把每块(长度为5)绑定到三个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是否有任何问题,正确alignment页面大小例如? 目前arraysA的大小为15,运行良好,但是如果我将数组大小重置为像6156000和piece = 2052000之类的值,随后三次调用mbind以&A [0]开始,&A [2052000]和&A [4104000 ]然后我得到一个分段错误(有时它只是挂在那里)。 为什么它运行小尺寸罚款,但更大给我段错误? 谢谢。

Solutions Collecting From Web of "numa,mbind,segfault"

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

numa内存的方式是,CPU插槽0的范围是0..X-1MB,插槽1有X..2X-1,插槽3有2X-3X-1等等。当然,如果你坚持插槽0旁边有4GB的ram棒,插槽1有16GB的ram棒,那么结果是不均匀的。 但是原理仍然是根据内存的实际位置为每个套接字分配一大块内存。

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

所以,对于大块“内存”来说,移动它很好,但是对于小块来说,它不会工作得很好 – 你当然不能将一个页面“拆分”成两个不同的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); 

显然,现在需要按照需要使用对齐的大小和余数来分割三个线程。