2016-02-22 11 views
7

を割り当てることができませんのmmap:私は(各3GB未満の - RAMのほとんどサイズ)2つの大きなファイルを持っている。このプログラムのためにC. でページフォルトサービス時間を計算するCプログラムを持っているメモリ

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include "rdstc.h" 
#include "config.h" 

#define KB 1024 
#define MB 1024 * KB 
#define GB 1024 * MB 
#define SIZE_OF_MEMORY 1 * GB // Main memory size 

#define handle_error(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0) 

int main(int argc, char *argv[]){ 

    int fd1, fd2; 
    char *addr1, *addr2, c; 
    int i, j; 
    long long unsigned int s_t, e_t, t=0; 

    if (argc != 3){ 
     printf("usage: a.out <file1> <file2> \n"); 
     exit(EXIT_FAILURE); 
    } 

    if ((fd1 = open(argv[1], O_RDONLY)) == -1){ 
     handle_error("open"); 
    } 

    if ((fd2 = open(argv[2], O_RDONLY)) == -1){ 
     handle_error("open"); 
    } 

    posix_fadvise(fd1, 0, 0, POSIX_FADV_RANDOM); 
    posix_fadvise(fd2, 0, 0, POSIX_FADV_RANDOM); 

    addr1 = (char *) mmap(0, SIZE_OF_MEMORY, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd1, 0); 
    if (addr1 == MAP_FAILED){ 
     handle_error("mmap"); 
    } 
    addr2 = (char *) mmap(0, SIZE_OF_MEMORY, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd2, 0); 
    if (addr2 == MAP_FAILED){ 
     handle_error("mmap"); 
    } 

    madvise(addr1, 0, MADV_RANDOM); 
    madvise(addr2, 0, MADV_RANDOM); 

    j = 32;  // default read ahead size if 256 blocks (assuming each block is of 512 bytes) 
    for(i = 0; i < ITERATIONS; i++){ 
     s_t = rdtsc(); 
      c = addr1[i + j*4*KB];  // read at multiple of page size, so every read causes a page fault 
      j *= 2; 
     e_t = rdtsc(); 
     t += (e_t - s_t); 
    } 
    printf("Time required to service a page faut is %f \n", (t/ITERATIONS)/CPU_FREQ); 

    munmap(addr1, SIZE_OF_MEMORY); 
    munmap(addr2, SIZE_OF_MEMORY); 

    return 0; 
} 

私は、次のコンパイラの警告を得る:

[email protected]:~/projects/mem$ gcc mem1_4.c -lm 
mem1_4.c: In function ‘main’: 
mem1_4.c:11:17: warning: integer overflow in expression [-Woverflow] 
#define MB 1024 * KB 
       ^
mem1_4.c:12:19: note: in expansion of macro ‘MB’ 
#define GB 1024 * MB 
       ^
mem1_4.c:13:28: note: in expansion of macro ‘GB’ 
#define SIZE_OF_MEMORY 2 * GB // Main memory size 
          ^
mem1_4.c:40:30: note: in expansion of macro ‘SIZE_OF_MEMORY’ 
    addr1 = (char *) mmap(0, SIZE_OF_MEMORY, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd1, 0); 
          ^
mem1_4.c:11:17: warning: integer overflow in expression [-Woverflow] 
#define MB 1024 * KB 
       ^
mem1_4.c:12:19: note: in expansion of macro ‘MB’ 
#define GB 1024 * MB 
       ^
mem1_4.c:13:28: note: in expansion of macro ‘GB’ 
#define SIZE_OF_MEMORY 2 * GB // Main memory size 
          ^
mem1_4.c:44:30: note: in expansion of macro ‘SIZE_OF_MEMORY’ 
    addr2 = (char *) mmap(0, SIZE_OF_MEMORY, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd2, 0); 
          ^
mem1_4.c:11:17: warning: integer overflow in expression [-Woverflow] 
#define MB 1024 * KB 
       ^
mem1_4.c:12:19: note: in expansion of macro ‘MB’ 
#define GB 1024 * MB 
       ^
mem1_4.c:13:28: note: in expansion of macro ‘GB’ 
#define SIZE_OF_MEMORY 2 * GB // Main memory size 
          ^
mem1_4.c:62:19: note: in expansion of macro ‘SIZE_OF_MEMORY’ 
    munmap(addr1, SIZE_OF_MEMORY); 
       ^
mem1_4.c:11:17: warning: integer overflow in expression [-Woverflow] 
#define MB 1024 * KB 
       ^
mem1_4.c:12:19: note: in expansion of macro ‘MB’ 
#define GB 1024 * MB 
       ^
mem1_4.c:13:28: note: in expansion of macro ‘GB’ 
#define SIZE_OF_MEMORY 2 * GB // Main memory size 
          ^
mem1_4.c:63:19: note: in expansion of macro ‘SIZE_OF_MEMORY’ 
    munmap(addr2, SIZE_OF_MEMORY); 
       ^

私はコマンドでそれを実行すると、私はエラーに

./a.out file1.txt file2.txt 
mmap: Cannot allocate memory 
を取得

コードは何をしますか? 我々はPROT_READ保護と一緒に旗に

MAP_PRIVATE(他のプロセスがこのファイルにアクセスするべきではありませんように)とMAP_POPULATE(よう

我々はMMAP(呼び出したとき)完全なファイルをメモリにマッピングされている)を使用してファイルの両方をマップフラグ。

最初にfile1をマップし、MAP_POPULATEを使用しているため、完全なRAMはこのファイルに対応するデータで埋められています。この後、同じフラグを使用してfile2をマップするので、file2はRAMに完全にマップされます。したがって、file1のデータにアクセスすると、file2は使用可能なすべてのRAMを占有するため、ページフォルトが発生します。また、MADV_RANDOMフラグが設定されたmadvise()システムコールは、カーネルに両方のファイルのページの読み込みを先読みしないように助言します。したがって、この初期設定は、使用可能なすべてのRAMを占有するファイル2で行われた後、file1に対応するデータにランダムにアクセスします(カーネルによって実行される先読み最適化の効果を避け、L3キャッシュからの読み取りも回避します)。ファイル2に対応するデータは、ファイルに対応するデータにアクセスするたびにページフォルトが発生します。我々は、ループ内のマッピングされた領域にわたって10回のランダムな読み取りを行い、この操作に必要な平均時間を測定する。

+0

コンパイラの警告があなたにヒントを与える必要があります - * 1024 * 1024 * 2 1024は負の数にオーバーフローしました。 – immibis

答えて

6

あなたが得る警告のコンパイラを見てください。ここで整数オーバーフローがあります:#define SIZE_OF_MEMORY 2 * GB。これは2^31 == 0b1000 ... 0に等しく、これは符号付きintの場合INT_MINに等しくなります。だからmmapが失敗するのです。

あなたの定義でunsigned literalsを使用する必要があります。

#define KB (1024u) 
#define MB (1024u * KB) 
#define GB (1024u * MB) 
#define SIZE_OF_MEMORY (2u * GB) 
+2

...とかっこを付けてください! – wildplasser

関連する問題