0

スタックに残すとエラーが発生するため、ヒープに割り当てた巨大な配列があります。私の知る限り、これをヒープに送信できる方法は 2 つあります。

#1

int i;
int x=10000, int y=10000;
double** array=(double**)malloc(sizeof(double*)*x);
if (image) {
    for (i=0; i<x; i++) {
        array[i] =(double*)malloc(sizeof(double)*y);
    }
}

#2

double *array[x][y]=(double*)malloc(sizeof(double)*x*y);

今、私はどの方法が優れているのだろうかと思っていましたか?#1は、ヒープ内の長さyのxブロックを要求していると思いますが、これらは隣り合っている必要はありません。#2は、ヒープ内のy * xのブロックを要求しています。#2はx * yの巨大なブロックを要求していますが、#1は接続する必要のないブロックを要求しています。それは分割される可能性があるため、#1は優れたものになります。ヒープが長さ x*y の巨大なストライプの取得を処理できなかったとすると、x 量の y ストライプのデータを処理できます。

まず、これは本当ですか?いずれかの方法について何か不足していますか? 私の議論は実際的でしょうか、それとも本当なら、ありそうなシナリオではありませんか? さらに優れた方法を手に入れましたか?

洞察をありがとう。

4

2 に答える 2

1

使用するメモリ アロケータと x と y の値によって異なります。

メモリ アロケータは、多くの場合、小さなメモリ ブロックをユーザー空間にキャッシュし、ユーザー空間で小さな割り当てを処理しますが、より大きな割り当て要求を 経由でカーネルに転送しますmmap

ほとんどのメモリ アロケータは次のように機能します。

void* malloc(size_t size)
    if (size > THRESHOLD) {
        return large_alloc(size)     // forward to mmap
    }
retry:
    void* ret = small_alloc(size);   // handled in user space
    if (ret == NULL) {               // no small blocks left
        enlarge_heap();              // map more memory from kernel
        goto retry;
    }
    return ret;
}

あなたのケースでは y == 10000 なので、80000 バイトのメモリ ブロックを要求しています。glibc のデフォルトのメモリ アロケータでは、mmap のしきい値は 128kB です。したがって、アロケータがすでに十分なメモリをキャッシュしている場合、このリクエストはユーザー空間で処理される傾向があります。ただし、#2 は 128kB より大きいため、mmap 呼び出しを呼び出します。

しかし、あなたの例では x == 10000 です。したがって、単一の mmap システムコール呼び出しとユーザー空間での 10000 割り当てについて話しているのです。私を信じて。#2ははるかに高速です:

最新の x86 マシンでは、高度に最適化されたアロケーター実装での割り当てには常に 70 サイクル以上かかります。10000 の割り当ては、700000 サイクル以上を消費します。ただし、通常の mmap 呼び出しのレイテンシは 100000 サイクルを超えないようにする必要があります。したがって、#2の方が優れています。

TCMalloc などの他のアロケーターの場合は少し異なります。TCMalloc にはそのようなしきい値がなく、常にそのSpan構造内のユーザー空間で大きな割り当て要求を処理しようとします。したがって、#2 は単一の割り当てしか必要としないため、間違いなくはるかに優れています。


#2はアロケーターが大きな連続したメモリブロックを見つける必要があるため、#1の方がより柔軟であることに同意します。ただし、これは仮想メモリ内でのみ連続していることに注意してください。物理ページは、最初に触れたときにオンデマンドでマップされます。これは、物理メモリ内で連続している必要がないことを意味します。また、多くの場合、仮想メモリ内で 8 * 10000 * 10000 バイトの連続したメモリ領域を簡単に見つけることができます。

于 2013-06-07T02:16:47.000 に答える