0

我正在 OS X 10.8.3 上开发。下面的代码很简单。它可以执行两个操作。如果未注释读取功能,则程序将在“地址”处打开文件并将其所有内容传输到数据中。相反,如果取消注释 memcpy 函数,程序会将映射的内容复制到数据中。我正在开发一个 Mac,它将常用文件缓存在 RAM 的非活动内存中,以便将来更快地访问。我在文件控制和 mmap 中都关闭了缓存,因为我正在处理 1 GB 或更大的大文件。如果我没有设置 NOCACHE 选项,则整个 1 GB 将存储在非活动内存中。

如果 read 函数未注释,则程序按预期运行。没有缓存任何内容,每次运行程序时,读取整个 1 GB 大约需要 20 秒。

但是,如果 memcpy 函数未注释,则会发生一些变化。我仍然看到内存没有增加,第一次运行时复制仍然需要 20 秒。但是前一次执行之后的每一次执行,都会在一秒钟内复制。这非常类似于将整个文件缓存在非活动内存中的行为,但我从未看到内存增加。即使我随后不映射文件而只执行读取,它也会在一秒钟内同时执行。

某些东西必须存储在非活动内存中,但是我该如何跟踪它以及如何跟踪它?我想找到正在存储的内容并将其用于我的优势。

我正在使用活动监视器查看一般内存大小。我正在使用 Xcode Instruments 将初始 memcpy 执行与 read 和 memcpy 都被注释的执行进行比较。我发现分配、文件活动、读取/写入、VM 跟踪器或共享内存工具没有区别。

#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;
}

更新:

对不起,如果我不清楚。在程序执行期间,我的 RAM 的活动内存部分根据我 malloc 的数据和映射文件的大小而增加。这肯定是页面所在的位置。清理后,可用内存量恢复到原来的水平。非活动内存永远不会增加。操作系统不会真正丢弃那些活动内存是有道理的,因为空闲内存是无用的,但由于以下原因,此过程与缓存不同。我测试了两种情况。在这两个文件中,我加载了一些总大小超过我可用内存的文件。一种情况是我缓存文件,另一种情况我不缓存。通过缓存,我的非活动内存增加了,一旦我填满了我的内存,一切都会大大减慢。加载新文件将替换另一个文件' s 分配了非活动内存,但此过程将花费比下一个场景更长的时间。下一个场景是关闭缓存。我再次运行程序几次加载足够的文件来填充我的内存,但非活动内存永远不会增加,活动内存总是恢复正常,所以看起来我什么也没做。我映射的文件仍然像以前一样快速加载,但是映射新文件会在正常时间内加载,替换其他文件。使用这种方法,我的系统永远不会变慢。为什么第二种情况更快?我映射的文件仍然像以前一样快速加载,但是映射新文件会在正常时间内加载,替换其他文件。使用这种方法,我的系统永远不会变慢。为什么第二种情况更快?我映射的文件仍然像以前一样快速加载,但是映射新文件会在正常时间内加载,替换其他文件。使用这种方法,我的系统永远不会变慢。为什么第二种情况更快?

4

1 回答 1

4

如果文件的页面不驻留在内存中,操作系统怎么可能使memcpy' d 文件工作?mmap操作系统会提示您不希望缓存数据,但如果它别无选择或者与内存没有更好的关系,它仍然会这样做。

您的页面的优先级最低,因为操作系统认为您不会再次访问它们。但是它们必须常驻memcpy才能工作,并且操作系统不会仅仅为了拥有可用内存而将它们丢弃(这是 100% 无用的)。非活动内存比空闲内存好,因为它至少有一些机会可以节省 I/O 操作。

于 2013-04-17T04:35:39.520 回答