6

次元 PageSize x PageSize の 2 次元配列を作成しながら、仮想ページ間での割り当ての影響を分析しています。私のマシンのページ サイズは 4096 です。4096 の整数 (行) を指す 4096 の整数ポインター (列) の配列があります。

新しい仮想ページで最初の整数ポインターの割り当てを開始したいと考えています。現在のメモリ位置が新しいページかどうかを確認するにはどうすればよいですか? それを特定したら、ガベージ値をいくつか書き込んで、ポインタを新しい仮想ページに移動できると思います。これが配列を割り当てる方法です。

    array = malloc(ncolumns * sizeof(int *));
    for(j = 0; j < ncolumns; j++)
    {
        array[j] = malloc(nrows * sizeof(int));
        if(array[j] == NULL)
        { reportError(8);}
    }
4

2 に答える 2

5

ページ サイズがわかっている場合は、新しく割り当てられたメモリの一部がページ境界に配置されることを保証する、十分なサイズのメモリを割り当てることができます。4096 バイト境界に 4096 バイトが整列されるようにするには、少なくとも 8192 バイトのメモリを割り当てる必要があります。

たとえば、呼び出しmallocて、(4097) にアラインされたオフセットが返された場合、0xDEAD1001メモリ アドレスの次のページに移動し0xDEAD2000て、4096 バイト アラインメントを取得する必要があります。次に、少なくとも 4096 バイトの連続したスペースが必要になります。したがって、8192 バイトを割り当てる必要があります。

4k バイトにアラインされたメモリ位置を取得するには、返されたアドレスに 4095 を追加しmalloc、最後の 3 バイトをマスクします。

void *mem = malloc(8192);
void *ptr = ((void *)mem+0x0FFF) & ~ (void *)0x0FFF;

編集:割り当てられた元のメモリへのポインタを保持して、後で向きを変えてそれを使用して を呼び出すことができるようにしてくださいfree()

今度は malloc が返されたとし0xDEAD000Fます。

0xDEAD000F + 0x0000FFF = 0xDEAD100E 
0xDEAD100E & ~0x0000FFF = 0xDEAD1000

この厄介なポインター演算をすべて実行したくない場合は、 を使用するだけでよいと思いますposix_memalign。ここでチェックしてください。別のプラットフォームを使用している場合は、同様のメモリ アラインメント サービスが利用できるはずです。

于 2013-09-26T05:19:35.883 に答える
3

C 言語の機能だけを使用すると、割り当て (つまり、malloc から返されたもの) をページ境界に合わせることができません。サンプルコードは、ポインターの配列を配列に割り当てているだけです。それらの場所は、仮想アドレス空間のどこにでも置くことができます。正確な場所は、コンパイラ/ライブラリ/OS/etc によって異なります。

通常、オペレーティング システムには、そのようなことを可能にする機能があります。WindowsではVirtualAlloc関数を使用できます。

于 2013-09-26T05:25:06.930 に答える