2013-04-17 42 views
0

我正在開發OS X 10.8.3。以下代碼很簡單。它可以執行兩個操作。如果閱讀功能未被註釋,則程序將在「地址」處打開該文件並將其全部內容轉換爲數據。相反,如果memcpy函數未被註釋掉,程序會將mmapped內容複製到數據中。我正在開發一個mac,它在RAM的非活動內存中緩存常用文件,以便更快速地訪問。我關閉了文件控制和mmap中的緩存,因爲我正在處理1 GB或更大的大文件。如果我沒有設置NOCACHE選項,整個1 GB將被存儲在非活動內存中。使用無效內存對我有利。這段代碼存儲在RAM或非活動內存中是什麼?

如果讀取功能未註釋,程序將按預期運行。沒有任何內容被緩存,每次程序運行時,大約需要20秒才能讀取整個1 GB。

但是,如果取而代之的是memcpy函數未註釋的東西發生了變化。儘管如此,我仍然看不到內存的增加,並且在第一次運行時仍需要20秒才能複製。但是之前的每一次執行,都會在一秒之內複製。這非常類似於將整個文件緩存在非活動內存中的行爲,但我從來沒有看到內存的增加。即使我沒有對文件進行mmap映射並且只執行讀取操作,它也會在相同的時間內執行,而不會執行讀取操作。

某些東西必須存儲在不活動的內存中,但是我該如何跟蹤它?我想找到正在存儲的內容,並將其用於我的優勢。

我正在使用活動監視器來查看一般內存大小。我使用Xcode Instruments將初始memcpy執行與read和memcpy都進行了註釋的執行進行比較。我在分配,文件活動,讀/寫,虛擬機跟蹤器或共享內存工具中看不到任何區別。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <sys/mman.h> 

int main(int argc, const char * argv[]) 
{ 
    unsigned char  *data; 
    unsigned char  *mmapdata; 
    size_t   length; 

    int file = open("address", O_RDONLY); 
    fcntl(file, F_NOCACHE, 1); 

    struct stat st; 
    stat("address", &st); 
    length = st.st_size; 

    data = malloc(length); 
    memset(data,0,length); 

    mmapdata = mmap(NULL, length, PROT_READ,MAP_SHARED|MAP_NOCACHE, file, 0); 
    if (mmapdata == MAP_FAILED) 
     fprintf(stderr, "failure"); 

// read(file,data,length); 
    close(file); 

// memcpy(data,mmapdata,length); 
    munmap(mmapdata,length); 

    free(data); 

    return 0; 
} 

UPDATE:

很抱歉,如果我還不清楚。在程序執行期間,我的RAM的活動內存部分根據數據I malloc和mmapped文件的大小而增加。這無疑是網頁所在的位置。清理之後,可用內存量恢復到之前的狀態。不活躍的內存永遠不會增加。因爲可用內存是無用的,所以操作系統不會真的丟掉活動內存,但這個過程與緩存不同,原因如下。我測試了兩種情況。在這兩個文件中,我加載了大小超過我的可用內存大小的文件。一個場景我緩存文件,一個我沒有。隨着緩存,我的不活動內存增加,一旦我填滿我的內存,一切都會大大減慢。加載新文件將替換另一個文件分配的非活動內存,但此過程需要的時間比下一個場景要長得多。下一個場景是緩存關閉。我再次運行該程序幾次加載足夠的文件來填充我的內存,但不活動的內存永遠不會增加,活動內存總是恢復正常,所以看起來我什麼也沒做。我已經映射的文件仍然像以前一樣快速加載,但是在正常時間內加載新文件並替換其他文件。用這種方法,我的系統永遠不會變慢。爲什麼第二種情況會更快?

回答

4

如果文件的頁面沒有駐留在內存中,操作系統如何在mmap'd文件上工作memcpy?操作系統提示你不要數據緩存,但如果它沒有選擇,或者沒有更好的內存使用方法,它仍然會提示你。

您的頁面的優先級最低,因爲操作系統相信您不會再訪問它們。但他們必須是memcpy的居民才能工作,並且操作系統不會爲了擁有可用內存(這是100%無用)而拋棄它們。非活動內存比空閒內存好,因爲至少有一些可能會節省I/O操作的機會。

+0

我添加了一個更新到我的問題的結尾。添加評論太長了。 – James491

+0

更新:第二種情況更快,因爲您使用的內存優先級較低,因此不會踢出緩存中重用的數據。 –

相關問題