4

さまざまなポリシーに基づいてメモリを割り当てるさまざまな手段を提供するカスタム アロケータがいくつかあります。それらの 1 つは、定義された NUMA ノードにメモリを割り当てます。アロケータへのインターフェースは単純です

template<typename config>
class NumaNodeStrategy
{

public:

    static void *allocate(const size_t sz){}

    static void *reallocate(void *old, size_t sz, size_t old_sz){}

    static void deallocate(void *p, size_t sz){}
};

割り当て自体はhwloc_alloc_membind_nodeset()、割り当てポリシーなどに応じてパラメーターが設定されたメソッドを使用して処理されます。ただし、hwloc はメモリの割り当てと解放のメソッドのみを提供し、どのように実装すればよいか疑問に思っていreallocate()ました。

考えられる解決策は次の 2 つです。

  1. memcpy()新しいメモリ領域とデータを割り当てます
  2. ノードセットのメモリ割り当て/バインディング ポリシーを設定するために使用hwloc_set_membind_nodeset()し、plain malloc()/ posix_memalign()andを使用しrealloc()ます。

誰かがこれを正しくするのを手伝ってくれますか?

アップデート:

質問をより具体的にしようとしています。新しいメモリを割り当てたり、ページを移動したりせずに、realloc()使用を実行する可能性はありますか?hwloc

4

3 に答える 3

2

編集への返信: hwloc には realloc はありません。現在、追加する予定はありません。必要なもの (関数の C プロトタイプ) が正確にわかっている場合は、お気軽にhttps://svn.open-mpi.org/trac/hwlocにチケットを追加してください。

ogsx への返信: メモリ バインディングは固有のものではなく、仮想メモリ領域固有のものであり、おそらくスレッド固有のものです。再割り当てした場合、libc は特別なことは何もしません。1) 同じページ内で再割り当てできる場合は、同じノードでメモリを取得します。特に大きなバッファーの場合は、良いですがまれです。2) 別のページで再割り当てする場合 (ほとんどの場合、大きなバッファーの場合)、対応するページが過去に malloc lib によって物理メモリに既に割り当てられているかどうかによって異なります (仮想メモリで malloc および解放されますが、まだ物理メモリに割り当てられています) 2.a) 仮想ページが割り当てられている場合、過去にさまざまな理由で別のノードに割り当てられている可能性があります。2.b) 新しい仮想ページがまだ割り当てられていない場合、デフォルトでは現在のノードに割り当てられます。以前に set_area_membind() または mbind() でバインドを指定した場合は、正しいノードに割り当てられます。この場合、あなたは幸せかもしれません。

要するに、それは多くのことに依存しています。複雑な/隠された内部処理を行う malloc lib に煩わされたくない場合、特にバッファが大きい場合は、malloc の代わりに mmap(MAP_ANONYMOUS) を実行すると、本当に必要なときにページが割り当てられるようにする簡単な方法になります。彼ら。また、realloc と同様のことを行う mremap もあります。

alloc は mmap(length) + set_area_membind になります realloc は mremap + set_area_membind になります (mremap されたバッファー全体で)

それを使用したことはありませんが、面白そうです。

于 2011-08-08T07:10:17.260 に答える
1

hwloc_set_area_membind_nodesetがうまく機能しますね。

 HWLOC_DECLSPEC int     
  hwloc_set_area_membind_nodeset (hwloc_topology_t topology, 
    const void *addr, size_t len, hwloc_const_nodeset_t nodeset, 
    hwloc_membind_policy_t policy, int flags)

(addr, len) で識別される割り当て済みのメモリをノードセットの NUMA ノードにバインドします。

戻り値:

  • アクションがサポートされていない場合は、ENOSYS に設定された errno で -1
  • -1 と errno が EXDEV に設定された場合 (バインディングを実施できない場合)

Linux では、この呼び出しはmbind 領域内のページに触れていない場合にのみ機能するため、2 番目のソリューションでメモリ領域を移動するためのより正しい方法です。更新には、タッチされたデータを移動するための MPOL_MF_MOVE* フラグがあります。

私が知っている唯一の再割り当てとコピーなしでページを移動するsyscallはmove_pagesです

move_pages は、実行されたプロセスのアドレス空間内の一連のページを別の NUMA ノードに移動します。

于 2011-08-04T09:13:55.463 に答える
1

あなたが間違っている。mbind は、タッチされたページを移動できます。MPOL_MF_MOVE を追加するだけです。これhwloc_set_area_membind_nodeset()は、 flag を追加した場合の動作ですHWLOC_MEMBIND_MIGRATE

move_pagesは別の方法です (より柔軟ですが、独立したページを別の場所に移動できるため、少し遅くなります)。mbind withMPOL_MF_MOVEと move_pages (および migrate_pages) の両方migrate_pages()が、入力をページのリストに変換すると、mm/migrate.c でまったく同じ関数を使用することになります。

于 2011-08-04T12:18:21.950 に答える