1

vallocを使用してメモリを割り当てました。たとえば、[15 * sizeof(double)]の配列Aとします。ここで、これを3つの部分に分割し、各部分(長さ5)を3つの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);

最初の質問は、私はそれを正しくやっているかということです。たとえば、ページサイズに適切に配置することに問題はありますか?現在、配列Aのサイズは15ですが、正常に実行されますが、配列サイズを6156000およびpiece = 2052000のようなものにリセットすると、その後、mbindへの3回の呼び出しは、&A [0]、&A [2052000]、および&A[4104000]で始まります。 ]その後、セグメンテーション違反が発生します(そして時々それがただそこにぶら下がっています)。なぜ小さいサイズでも問題なく動作するのに、大きいサイズではセグメンテーション違反が発生するのですか?ありがとう。

4

1 に答える 1

1

これを機能させるには、少なくともページサイズでページ整列されたメモリのチャンクを処理する必要があります。これは、ほとんどのシステムで4KBを意味します。あなたの場合、3mbind()回電話をかけたため、ページが2回(おそらく3回)移動したと思われます。

NUMAメモリの配置方法は、CPUソケット0の範囲が0..X-1 MB、ソケット1の範囲がX..2X-1、ソケット3の範囲が2X-3X-1などです。ソケット0の横に4GBのRAMがあり、ソケット1に16GBのRAMがある場合、分散は均一ではありません。ただし、メモリが実際に配置されている場所に応じて、各ソケットに大量のメモリが割り当てられるという原則があります。

メモリの配置方法の結果として、使用しているメモリの物理的な場所は、ページマッピングによって線形(仮想)アドレス空間に配置する必要があります。

したがって、メモリの大きな「チャンク」の場合は移動しても問題ありませんが、小さなチャンクの場合は正しく機能しません。ページを2つの異なる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);

明らかに、必要に応じて、位置合わせされたサイズとレムナントを使用して、同様に3つのスレッドを分割する必要があります。

于 2013-01-25T19:12:18.897 に答える