Tag: mmap

内存映射文件和指向易失性对象的指针

我对C和C ++中volatile的语义的理解是它将内存访问转化为(可观察的)副作用 。 每当读取或写入内存映射文件(或共享内存)时,我都希望指针是volatile限定的,以表明这实际上是I / O. (John Regehr写了一篇关于volatile的语义的非常好的文章 )。 此外,我希望使用像memcpy()这样的函数来访问共享内存是不正确的,因为签名表明易失性限定被丢弃,并且内存访问不被视为I / O. 在我看来,这是一个支持std::copy() ,其中volatile限定符不会被丢弃,并且内存访问被正确地视为I / O. 但是,我使用指向volatile对象的指针和std::copy()访问内存映射文件的经验是,它比使用memcpy()要慢memcpy()数量级。 我很想得出结论,或许clang和海湾合作委员会在处理volatile上过于保守。 是这样的吗? 关于volatile访问共享内存有什么指导,如果我想遵循标准的字母并让它依赖我依赖的语义? 标准[intro.execution]§14的相关引用: 读取由volatile glvalue指定的对象,修改对象,调用库I / O函数或调用执行任何这些操作的函数都是副作用,这些都是执行环境状态的变化。 表达式(或子表达式)的评估通常包括值计算(包括确定用于glvalue评估的对象的身份以及获取先前分配给用于prvalue评估的对象的值)和启动副作用。 当对库I / O函数的调用返回或通过volatile glvalue进行访问时,即使调用所隐含的某些外部操作(例如I / O本身)或易失性访问,也会认为副作用已完成可能尚未完成。

为什么POSIX mmap没有返回volatile void *?

Mmap返回void *,但不返回volatile void* 。 如果我正在使用mmap来映射共享内存,那么另一个进程可能正在写入该内存,这意味着来自同一内存位置的两个后续读取可能会产生不同的值 – 这意味着volatile的确切情况。 那么为什么它不会返回一个易变的空隙*? 我最好的猜测是,如果你有一个专门写入共享内存段的进程,它不需要通过volatile指针查看共享内存,因为它总能正确理解存在的内容; 编译器为防止冗余读取所做的任何优化都无关紧要,因为没有其他任何内容可以写入并更改其下的值。 还是有其他一些历史原因? 我倾向于说返回volatile void*将是一个更安全的默认值,那些想要这个优化的人可以手动转换为void *。 POSIX mmap说明: http : //opengroup.org/onlinepubs/007908775/xsh/mmap.html

达尔文真的没有mmap吗?

我试图找出如何在Mac上重新映射内存映射文件(当我想扩展可用空间时)。 我看到我们在Linux世界中的朋友都有mremap但我在Mac上的标题中找不到这样的function。 /Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h具有以下内容: mmap mprotect msync munlock munmap 但没有mremap man mremap证实了我的恐惧。 如果我想调整映射文件的大小,我当前需要munmap和mmmap ,这涉及使所有加载的页面无效。 肯定有更好的办法。 一定? 我正在尝试编写适用于Mac OS X和Linux的代码。 如果我必须这样做,我可以满足于在每种情况下使用最佳function的宏,但我宁愿正确地做。

在C中使用mmap写入内存。

我想使用mmap()创建一个包含一些整数的文件。 我想通过写入内存来写入此文件。 我知道内存中的数据是二进制格式,因此文件中的数据也是二进制的。 我可以为此目的使用mmap吗? 我在哪里可以找到有关如何使用mmap好资源? 我没有找到一本好的手册。

C – 内存映射B树

我正在尝试记忆映射一个巨大的文件(大约100GB),以便存储具有数十亿个键值对的B树。 内存很小,以便将所有数据保存在内存中,因此我试图从磁盘映射文件而不是使用malloc我返回并递增指向映射区域的指针。 #define MEMORY_SIZE 300000000 unsigned char *mem_buffer; void *start_ptr; void *my_malloc(int size) { unsigned char *ptr = mem_buffer; mem_buffer += size; return ptr; } void *my_calloc(int size, int object_size) { unsigned char *ptr = mem_buffer; mem_buffer += (size * object_size); return ptr; } void init(const char *file_path) { int fd = open(file_path, O_RDWR, S_IREAD […]

MAP_ANONYMOUS符合C99标准

我有一个使用mmap系统调用的应用程序,我有一个问题,让它编译几个小时,看看为什么我得到MAP_ANON和MAP_ANONYMOUS未声明,我有一小部分代码,我用过,我看到我可以编译它就好了,所以我尝试了一个基本的编译,这工作,我看到它添加-std = c99失败。 是否有特定原因导致MAP_ANON和MAP_ANONYMOUS在C99标准中无效? 我知道它们不是由POSIX定义的,而是由BSD SOURCE定义的,所以我只想知道为什么会这样。

为什么mmap无法分配内存?

我使用root权限运行该程序,但它一直在抱怨mmap无法分配内存。 代码段如下: #define PROTECTION (PROT_READ | PROT_WRITE) #define LENGTH (4*1024) #ifndef MAP_HUGETLB #define MAP_HUGETLB 0x40000 #endif #define ADDR (void *) (0x0UL) #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB) int main (int argc, char *argv[]){ … // allocate a buffer with the same size as the LLC using huge pages buf = mmap(ADDR, LENGTH, PROTECTION, FLAGS, […]

C中的Mmap和struct

我想在C中用mmap读写结构。 我有一个名为insert_med的函数,它允许在mmap中插入一个新的struct med ,并且每个struct(带有一个唯一的键 )都必须写在数组的不同位置(当添加一个新结构时,它必须是添加在数组的最后一个空位置)。 两个结构med不能具有相同的密钥,如下面的代码所示。 关键是独一无二的。 我的代码不起作用 – 带有变量“struct map”的错误消息:声明时和文件准备好mmapped时 – 但我不知道为什么。 我想我可能做错了事。 #include #include #include #include #include #include #include #define FILEPATH “/tmp/mmapped.bin” #define NUMINTS (1000) #define FILESIZE (NUMINTS * sizeof(int)) struct med{ int key; char name[25]; int quant_min; int quant; }; insert_med(int argc, char *argv[]){ int i; int fd; int result; struct map*; […]

使用`madvise`清零大内存映射

我有以下问题: 我通过mmap与MAP_ANONYMOUS分配了一大块内存(多个GiB)。 该块包含一个大的哈希映射,需要时不时地归零。 并非整个映射可以在每一轮中使用(并非每个页面都有错误),因此memset不是一个好主意 – 需要太长时间。 快速做到这一点的最佳策略是什么? 将 madvise(ptr, length, MADV_DONTNEED); 保证我任何后续访问都提供新的空页? 来自Linux man madvise页面: 此调用不会影响应用程序的语义( MADV_DONTNEED除外 ),但可能会影响其性能。 内核可以自由地忽略这些建议。 … MADV_DONTNEED 对此范围内的页面的后续访问将成功,但将导致从底层映射文件(请参阅mmap(2))或零填充按需页面重新加载内存内容,以便在没有基础文件的情况下进行映射。 … 当前的Linux实现(2.4.0)将此系统调用视为命令而不是建议… 或者我是否必须重新映射并重新映射该区域? 它必须在Linux上工作,理想情况下在OS X上具有相同的行为。

如何使用mmap在堆中分配内存?

只是问题陈述,如何使用mmap()在堆中分配内存? 这是我唯一的选择,因为malloc()不是可重入函数。