Dav*_*dia 5 memory performance kernel driver linux-kernel
我正在开发一个 Linux 内核驱动程序,它为用户空间提供一块物理内存。我有驱动程序的工作版本,但目前速度很慢。所以,我退回了几步,尝试制作一个小巧、简单的驱动程序来重现问题。
我在启动时使用内核参数保留内存memmap=2G$1G。然后,在驱动程序的__init函数中,我ioremap将这些内存中的一部分,并将其初始化为一个已知值。我也输入了一些代码来测量时间:
#define RESERVED_REGION_SIZE (1 * 1024 * 1024 * 1024) // 1GB
#define RESERVED_REGION_OFFSET (1 * 1024 * 1024 * 1024) // 1GB
static int __init memdrv_init(void)
{
struct timeval t1, t2;
printk(KERN_INFO "[memdriver] init\n");
// Remap reserved physical memory (that we grabbed at boot time)
do_gettimeofday( &t1 );
reservedBlock = ioremap( RESERVED_REGION_OFFSET, RESERVED_REGION_SIZE );
do_gettimeofday( &t2 );
printk( KERN_ERR "[memdriver] ioremap() took %d usec\n", usec_diff( &t2, &t1 ) );
// Set the memory to a known value
do_gettimeofday( &t1 );
memset( reservedBlock, 0xAB, RESERVED_REGION_SIZE );
do_gettimeofday( &t2 );
printk( KERN_ERR "[memdriver] memset() took %d usec\n", usec_diff( &t2, &t1 ) );
// Register the character device
...
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我加载驱动程序,并检查 dmesg。它报告:
[memdriver] init
[memdriver] ioremap() took 76268 usec
[memdriver] memset() took 12622779 usec
Run Code Online (Sandbox Code Playgroud)
这是 memset 的 12.6 秒。这意味着 memset 以81 MB/sec 的速度运行。为什么地球这么慢?
这是 Fedora 13 上的内核 2.6.34,它是一个 x86_64 系统。
编辑:
该方案背后的目标是获取一块物理内存,并使其可用于 PCI 设备(通过内存的总线/物理地址)和用户空间应用程序(通过调用mmap,由驱动程序支持)。然后 PCI 设备将不断地用数据填充这个内存,用户空间应用程序将读取它。如果ioremap这样做是一种不好的方法(正如 Ben 在下面建议的那样),我愿意接受其他建议,这些建议将使我能够获得任何可由硬件和软件直接访问的大块内存。我也可以使用较小的缓冲区。
请参阅下面我的最终解决方案。