我有一个简单的程序试图访问用户空间中的物理内存,其中内核存储第一个结构页面.在64位机器上,此地址为:
我试图通过用户空间中的mmap访问此物理地址.但是下面的代码崩溃了内核.
int *addr;
if ((fd = open("/dev/mem", O_RDWR|O_SYNC)) < 0 ) {
printf("Error opening file. \n");
close(fd);
return (-1);
}
/* mmap. address of first struct page for 64 bit architectures
* is 0x0000620000000000.
*/
addr = (int *)mmap(0, num*STRUCT_PAGE_SIZE, PROT_READ, MAP_PRIVATE,
fd, 0x0000620000000000);
printf("addr: %p \n",addr);
printf("addr: %d \n",*addr); /* CRASH. */
Run Code Online (Sandbox Code Playgroud) 根据我的理解,mmap'适合RAM的文件就像将文件放在内存中一样.
假设我们有16G的RAM,我们首先mmap我们使用了一段时间的10G文件.这在访问方面应该相当有效.如果我们然后mmap第二个10G文件,那会导致第一个被换出吗?还是它的一部分?如果是这样,这会发生什么时候?在mmap调用,或访问新加载的文件的内存区域?
如果我们想再次访问第一个文件的指针内存,是否会使它再次加载交换文件?那么,假设我们在对应于第一个文件和第二个文件的内存之间交替读取,是否会导致灾难性的性能?
最后,如果这是真的,那么mmap几个较小的文件会更好吗?
我正在使用我在Linux中的Direct Memory Access上发布的驱动程序将一些物理ram映射到用户空间地址.但是,我无法使用GDB来查看任何地址; 即,x 0x12345678(其中0x12345678是mmap的返回值)失败,并显示错误"无法访问地址0x12345678处的内存".
有没有办法告诉GDB可以查看这个内存?或者,我在mmap中可以做些什么(在foo_mmap的调用或实现),它将允许它访问这个内存?
请注意,我不是在询问/ dev/mem(如在那里的第一个片段中),而是关于通过ioremap(),virt_to_phys()和remap_pfn_range()获取的内存的mmap
可以从linux 2.6.30+下的用户空间访问(非共享)mmap页面的肮脏吗?平台特定的黑客和kludges欢迎.
理想情况下,我正在寻找一个位数组,每页一个(4kB?)mmap的区域,如果该页面已被写入,则设置该区域是mmap的.
(我知道,写作过程可以跟踪这些信息 - 但如果内核正在这样做,那么这样做似乎很愚蠢.)
谢谢,
克里斯.
上下文是进程间通信,其中一个进程("服务器")必须将固定大小的结构发送到在同一台机器上运行的许多侦听进程("客户端").
在Socket Programming中我很自在.为了使服务器和客户端之间的通信更快并减少副本数量,我想尝试使用共享内存(shm)或mmaps.
操作系统是RHEL 64位.
由于我是新手,请建议我应该使用哪个.如果有人能指点我一本书或在线资源来学习同样的东西,我会很感激.
谢谢你的回答.我想补充一点,服务器(市场数据服务器)通常会接收多播数据,这将导致它每秒向"客户端""发送"大约200,000个结构,其中每个结构大约为100字节.shm_open/mmap的实现是否仅对大型数据块或大量小型结构的性能优于套接字?
假设您有一个巨大的(40+ GB)特征值(浮点)矩阵,行是不同的特征,列是样本/图像.
该表是按列预先计算的.然后,它被完全访问行和多线程(每个线程加载整行)几次.
处理这个矩阵的最佳方法是什么?我特别琢磨超过5分:
我花了一些时间研究我正在处理的应用程序的内存映射IO.我有一些非常大的(TB级)文件,我想将它们的段映射到内存中,用于读取和写入,最大限度地利用操作系统级缓存.我正在编写的软件需要在Unix/Linux和Windows下运行......性能至关重要.
我发现boost::iostreams::mapped_file_source和boost::iostreams::mapped_file_sink,其提供了大部分我在寻找的设施.我喜欢但尚未找到的设施是:
msync在Unix FlushViewOfFile上为(2); 在Windows上)我可以使用这些东西"boost/iostreams/device/mapped_file.hpp"吗?是否有其他独立于平台的库可以更好地满足我的要求?我必须开发自己的跨平台库才能获得这种灵活性吗?
我想检测特定页面是否已在内存中映射.这里的目标是能够在使用固定内存地址调用mmap之前执行此检查.以下代码说明了默认情况下发生的情况:mmap以静默方式重新映射原始内存页.
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int page_size;
void *ptr;
page_size = getpagesize();
ptr = mmap(0, 10 * page_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (ptr == MAP_FAILED) {
printf ("map1 failed\n");
return 1;
}
((int *)ptr)[0] = 0xdeadbeaf;
ptr = mmap(ptr, 2 * page_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
if (ptr == MAP_FAILED) {
printf ("map2 failed\n");
return 1;
}
if (((int *)ptr)[0] != 0xdeadbeaf) { …Run Code Online (Sandbox Code Playgroud) 我编写了一个linux驱动程序,ioremaps将特定设备的PCI BAR0导出到sysfs二进制属性,允许用户空间直接控制它.
当我尝试在属性之上进行MMAP以直接访问该位内存(来自userland程序)时,问题就出现了.读取成功并返回预期值,但是当我写入该内存时,它似乎缓存在内核和内存之间的某处,而不是传递给GMCH根复合体(因此也就是设备).我想做的是每次访问后都有一个隐含的写内存屏障.
跟进: