c - 这是使用内存映射来存储大量数据的有效方法吗?

标签 c linux

我正在开发一个堆叠天文图像的程序。它将涉及必须在内存中存储数百个 16 位 RGB 图像以进行处理。我不能一次只处理一张图像,因为在某些情况下我想取每个像素的中值。我决定创建临时文件并将我的图像 mmap 到它们,这样我就可以使用我的图像 api,就像图像在正常内存中或被 mmaped 之间没有任何变化一样,因为内核应该处理在幕后访问文件的必要部分。我发布这个是因为我只是想确保我做的是正确的。如果我只有 16GB 的 ram + 我的 8GB 交换分区,这种方法是否可以加载 50gb 的图像(假设)?

typedef struct
{
    size_t w;
    size_t h;
    pixel_t px[];
} image_t;

//allocate in normal memory
image_t* image_new(size_t w, size_t h)
{
    assert(w && h);
    image_t* img = malloc(sizeof(image_t) + sizeof(pixel_t) * w * h);
    if(!img)
        return NULL;

    img->w = w;
    img->h = h;

    memset(img->px, 0, sizeof(pixel_t) * w * h);

    return img;
}

image_t* image_mmap_new(image_t* img)
{
    FILE* tmp = tmpfile();
    if(tmp == 0)
        return NULL;
    size_t wsize = sizeof(image_t) + sizeof(pixel_t) * img->w * img->h;
    if(fwrite(img, 1, wsize, tmp) != wsize)
    {
        fclose(tmp);
        return NULL;
    }

    image_t* nimg = mmap(NULL, wsize, PROT_WRITE | PROT_READ, MAP_SHARED, fileno(tmp), 0);
    fclose(tmp);
    return nimg;
}

最佳答案

据我所知,唯一的限制是地址空间。映射后,文件就像内存区域一样被访问,只有实际使用的部分才会加载到内存中。

此(旧但有效)GNU 库文档中的更多信息: http://www.gnu.org/software/libc/manual/html_node/index.html#toc-Introduction-1

其实我好像太保守了,你可以映射更大的文件:How big can a memory-mapped file be?

关于c - 这是使用内存映射来存储大量数据的有效方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33617964/

相关文章:

linux - 如何确定我的 shell 管道中最慢的组件?

python - 为什么使用 sudo 运行脚本或使用 crontab 计划会导致错误?

c++ - 源码分析工具?

c - 如何终止后台 ssh 实例

c++ - 内存浪费?如果 main() 应该只返回 0 或 1,为什么 main 声明为 int 而不是 short int 甚至 char?

linux - 如何从 bash 脚本启动交互式 ssh 终端?

linux - 服务器修补电子邮件通知 Linux 脚本

c - JACK 语言的 Lexer 中的段错误

c - 如何检查不同速度的球与桨之间的碰撞

linux - 在 if 条件中使用 bash 算术运算符时结果不正确