c – mbind返回EINVAL
我正在使用为以下问题
numa+mbind+segfault提供的代码,每次调用mbind都会返回EINVAL.我怎样才能得到完全错误的东西?我问这个是因为EINVAL可以归还很多原因.
page_size = sysconf(_SC_PAGESIZE); objs_per_page = page_size/sizeof(A[0]); assert(page_size%sizeof(A[0])==0); split_three=num_items/3; aligned_size=(split_three/objs_per_page)*objs_per_page; remnant=num_items-(aligned_size*3); piece = aligned_size; nodemask=1; mbind(&A[0],piece*sizeof(double),MPOL_BIND,&nodemask,64,MPOL_MF_MOVE); nodemask=2; mbind(&A[aligned_size],MPOL_MF_MOVE); nodemask=4; bind(&A[aligned_size*2+remnant],MPOL_MF_MOVE); 在运行程序之后(通过在每次mbind调用之前将节点掩码分别更改为1,2和4)如下所示(作为Mats Petersson的答案).它有时会出现段错误,有时会运行良好.当它发生段错误时,dmesg如下: Stack: Call Trace: mpol_new+0x5d/0xb0 sys_mbind+0x125/0x4f0 finish_task_switch+0x4a/0xf0 ? __schedule+0x3cf/0x7c0 system_call_fastpath+0x16/0x1b Code: ... kmem_cache_alloc+0x58/0x130 解决方法
查看Linux内核的源代码,您可以获得EINVAL:
>传入无效模式值.超出“不一致”的范围(同时使用静态和相对节点) 我的猜测是在开始时不是页面对齐的. 这段代码适合我: #include <numaif.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #define ASSERT(x) do { if (!(x)) do_assert(#x,(long)(x),__FILE__,__LINE__); } while(0) static void do_assert(const char *expr,long expr_int,const char *file,int line) { fprintf(stderr,"ASSERT failed %s (%d) at %s:%dn",expr,expr_int,file,line); perror("Error if present:"); exit(1); } int main() { size_t num_items = 6156000; double *A = valloc(num_items * sizeof(double)); ASSERT(A != NULL); int res; unsigned long nodemask; size_t page_size = sysconf(_SC_PAGESIZE); size_t objs_per_page = page_size/sizeof(A[0]); ASSERT(page_size%sizeof(A[0])==0); size_t split_three=num_items/3; size_t aligned_size=(split_three/objs_per_page)*objs_per_page; size_t remnant=num_items-(aligned_size*3); size_t piece = aligned_size; printf("A[0]=%pn",&A[0]); printf("A[%d]=%pn",piece,&A[aligned_size]); printf("A[%d]=%pn",2*piece,&A[2*piece]); nodemask=1; res = mbind(&A[0],MPOL_MF_MOVE); ASSERT(res ==0); nodemask=1; res = mbind(&A[aligned_size],MPOL_MF_MOVE); ASSERT(res ==0); nodemask=1; res = mbind(&A[aligned_size*2],(piece+remnant)*sizeof(double),MPOL_MF_MOVE); ASSERT(res == 0); } 请注意,我在所有分配中使用“nodemask = 1”,因为我的机器中只有一个四核处理器,因此没有其他节点可以绑定 – 这也给出了EINVAL.我认为你实际上系统中有多个节点. 我还将“残余”从A []移动到最后一次mbind调用的剩余大小. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |