我的机器不应该有一个 /dev/ram0 文件吗?

我的机器不应该有一个 /dev/ram0 文件吗?

我有一个大学作业,需要创建一个 RAM 磁盘。

有人告诉我要制作一个 C 程序,对 RAM 磁盘内的文件进行多次写入,然后对硬盘上的文件执行相同操作,以比较写入速度。

为了创建 RAM 磁盘,我获得了以下脚本:

#!/bin/bash
# RAM Disk
ROOTUSER_NAME=root
MOUNTPT=/tmp/ramdisk
SIZE=2024 # 2K blocs
BLOCKSIZE=1024 # block size: 1K (1024 bytes)
DEVICE=/dev/ram0 # First RAM Disk
username=`id -nu`
[ "$username" != "$ROOTUSER_NAME" ] && echo "not authorised" && exit 1
[ ! -d "$MOUNTPT" ] && mkdir $MOUNTPT
dd if=/dev/zero of=$DEVICE count=$SIZE bs=$BLOCKSIZE
/sbin/mkfs -t ext4 $DEVICE 
mount $DEVICE $MOUNTPT # the mount
chmod 777 $MOUNTPT
echo $MOUNTPT " ready"
exit 0

这里的问题是,我的机器似乎没有该/dev/ram0目录/dev;这是输出ls /dev

ferran@amsa:~/Desktop$ ls /dev
autofs          lightnvm    sda     tty22  tty5     ttyS18   vcs3
block           log         sda1    tty23  tty50    ttyS19   vcs4
bsg             loop0       sda2    tty24  tty51    ttyS2   vcs5
btrfs-control   loop1       sda3    tty25  tty52    ttyS20   vcs6
bus             loop2       sda5    tty26  tty53    ttyS21   vcsa
cdrom           loop3       sg0     tty27  tty54    ttyS22   vcsa1
cdrw            loop4       sg1     tty28  tty55    ttyS23   vcsa2
char            loop5       shm     tty29  tty56    ttyS24   vcsa3
console         loop6       snapshot  tty3   tty57      ttyS25   vcsa4
core            loop7       snd     tty30  tty58    ttyS26   vcsa5
cpu             loop8       sr0     tty31  tty59    ttyS27   vcsa6
cpu_dma_latency  loop9      stderr  tty32  tty6     ttyS28   vcsu
cuse            loop-control  stdin     tty33  tty60    ttyS29   vcsu1
disk            mapper      stdout  tty34  tty61    ttyS3   vcsu2
dma_heap        mcelog      tty     tty35  tty62    ttyS30   vcsu3
dmmidi          mem         tty0    tty36  tty63    ttyS31   vcsu4
dri             midi        tty1    tty37  tty7     ttyS4   vcsu5
dvd             mqueue      tty10   tty38  tty8     ttyS5   vcsu6
ecryptfs        net         tty11   tty39  tty9     ttyS6   vfio
fb0             null        tty12   tty4   ttyprintk  ttyS7 vga_arbiter
fd              nvram       tty13   tty40  ttyS0    ttyS8   vhci
full            port        tty14   tty41  ttyS1    ttyS9   vhost-net
fuse            ppp         tty15   tty42  ttyS10   udmabuf  vhost-vsock
hidraw0         psaux       tty16   tty43  ttyS11   uhid    vmci
hpet            ptmx        tty17   tty44  ttyS12   uinput   zero
hugepages       pts         tty18   tty45  ttyS13   urandom  zfs
hwrng           random      tty19   tty46  ttyS14   userio
initctl         rfkill      tty2    tty47  ttyS15   vcs
input           rtc         tty20   tty48  ttyS16   vcs1
kmsg            rtc0        tty21   tty49  ttyS17   vcs2

这是输出fdisk -l

ferran@amsa:~/Desktop$ sudo fdisk -l
[sudo] password for ferran:
Disk /dev/loop0: 4 KiB, 4096 bytes, 8 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop1: 55,45 MiB, 58130432 bytes, 113536 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop2: 65,22 MiB, 68378624 bytes, 133552 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop3: 55,51 MiB, 58191872 bytes, 113656 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop4: 65,1 MiB, 68259840 bytes, 133320 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop5: 50,98 MiB, 53432320 bytes, 104360 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop6: 32,3 MiB, 33865728 bytes, 66144 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop7: 32,45 MiB, 34017280 bytes, 66440 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/sda: 100 GiB, 107374182400 bytes, 209715200 sectors
Disk model: VMware Virtual S
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x70d3f840

Device  Boot    Start       End   Sectors  Size Id Type
/dev/sda1  *        2048 117186559 117184512 55,9G 83 Linux
/dev/sda2       117188606 132810751  15622146  7,5G  5 Extended
/dev/sda3       132810752 132812799     2048    1M 82 Linux swap / Solaris
/dev/sda5       117188608 132810751  15622144  7,5G 82 Linux swap / Solaris

Partition table entries are not in disk order.


Disk /dev/loop8: 219 MiB, 229638144 bytes, 448512 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

对于写入速度测试,我使用以下 C 程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 10000000

int main(int argc, char *argv[]){

    char *c =               /* This is compiled into one long string, with no newlines. */
         "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
         "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
         "Ut enim ad minim veniam, quis nostrud exercitation                "
         "ullamco laboris nisi ut aliquip ex ea commodo consequat. "
         "Duis aute irure dolor in reprehenderit in voluptate velit esse "
         "cillum dolore eu fugiat nulla pariatur. Excepteur sint                "
         "occaecat cupidatat non proident, sunt in culpa qui "
         "officia deserunt mollit anim id est laborum.";
    FILE *fp;

    fp = fopen(argv[1],"w");
    for(int i=0; i < MAX; i++){
        fputs(c,fp);
        fseek(fp, 0, SEEK_SET);
    }
    fclose(fp);
}

我叫它两次:

  1. ./writeTest ~/Desktop/test
  2. ./writeTest /tmp/ramdisk/test

而且结果不太令人信服,因为 RAM Disk 文件需要 8 秒,而硬盘文件需要 11 秒,这似乎不是我应该获得的改进,对吗?

当我运行 bash 脚本时,它/dev/ram0会被创建,但我不知道这是否是应该发生的,写入速度的提高是否符合预期,或者我是否应该已经/dev/ram0在我的/dev目录中创建了一个。

任何帮助,将不胜感激。

编辑1:

我按照@user1686说的做了些改动,首先加载了需要的模块modprobe brd,然后就全都出现了。/dev/ram#

然后,我尝试改进我的 C 程序以减少seek调用,尽管我知道通过这种方式测试写入速度不是最好的主意,但我被告知使用 C 程序来做(也许目标只是我们看到在 RAM 而不是硬盘上写入时有所改进,而不是我们知道写入速度的确切增量)。

为了减少seek调用,我把 RAM 磁盘做得更大(从 2 MB 增加到 32 MB),然后,不再调用seek循环的每次迭代,而是估算出写入近 32 MB 需要多少次循环,然后每次MAX迭代我都调用seek,最后重复外循环LOOPS次数。

该程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LOOPS 50
#define MAX 70000

int main(int argc, char *argv[]){

        char *c = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor inci";

        FILE *fp;

        fp = fopen(argv[1],"w");
        for(int i=0; i < LOOPS; i++){
                for(int i=0; i < MAX; i++){
                        fputs(c,fp);
                }
                fseek(fp, 0, SEEK_SET);
        }
        fclose(fp);
}

使用此新版本并且安装了主硬盘和 RAM 磁盘的sync选项,我设法获得了 30 倍更快的改进,并且随着我增加的值,它似乎还在增加LOOPS

答案1

我的机器不应该有一个 /dev/ram0 文件吗?

是也不是,但大多情况下不是。

Linux 确实有一个可以提供/dev/ram#设备的“ramdisk”驱动程序,它可能是可用的在你的系统上,但通常未加载默认情况下,除非您先加载该驱动程序,否则这些设备节点将不存在。为此,插入brd.ko内核模块,您应该会得到 8 或 16 个ram设备:

# modprobe brd

如果驱动程序未加载,而你的脚本盲目地使用 创建了 /dev/ram0 dd,那么它并没有以这种方式创建 ramdisk——它创建了一个文件。(你实际上应该删除它加载“brd”驱动程序。)

然而,幸运的是,即使没有 /dev/ram0,您的脚本仍然最终实现了“更好的写入速度”的目标。这是因为在大多数 Linux 系统上,整个 /dev 并不存储在物理磁盘上,而是tmpfs在其上挂载了一个文件系统1

内存中已经有一个“tmpfs”——有点儿类似于使用 ramdisk,不同之处在于 ramdisk 是固定大小的并且需要与另一个文件系统结合,而 tmpfs 本身的大小是动态的。

因此,您在 /dev 中创建的任何新文件(有时在 /tmp 中也是如此都将完全存储在内存中。即使您的脚本没有建立一个真正的旧式“ramdisk”,但仅仅创建了一个名为“/dev/ram0”的常规文件3,它存储在 tmpfs 上这一事实意味着您仍然可以获得预期的速度提升。4

(但是您也可以通过将 ./writeTest 程序直接指向 /dev/testfile 来获得该信息。)

简而言之,虽然 Linux 有 ramdisk,但 tmpfs 几乎在所有情况下都是 ramdisk 的现代替代品。您无需决定其大小,也无需明确“mkfs”文件系统 - 只需在需要的地方安装 tmpfs 即可:

# mount -t tmpfs horse /tmp/ramdisk

1(开启最多如今的 Linux 系统,/dev 使用“devtmpfs”,这是一种特殊的 tmpfs 变体,其中设备节点会在驱动程序识别设备后立即自动出现;例如,只要您加载“brd”驱动程序,/dev/ram0 就会完全自动出现。但除此之外,它的行为就像常规 tmpfs。)

2(使用findmntmount检查您的发行版是否确实在 /tmp 上安装了 tmpfs。)

3(即使它是一个文件,您仍然可以像磁盘一样安装它,因为该mount命令在 2011 年已更新,可以自动设置“循环设备”,而无需-o loop指定。)


但结果并不令人信服,因为 RAM 文件需要 8 秒,而硬盘文件需要 11 秒,这似乎不是我应该获得的改进,对吗?

两个测试运行速度一样快的一个原因是写入缓冲的在内存中——您的程序不会等待每次写入都完全提交到磁盘后再继续下一次写入;相反,所有内容都会以短时间的突发方式写入磁盘。

(由于你的程序会返回 0 并完全覆盖数据,因此可能不是很多需要从缓冲区移动到磁盘。

两个测试都运行得很快的另一个原因是现代硬盘相当快,SSD 的速度更快。同时,如果你的作业要求你设置一个 ramdisk,这让我觉得它是在 1999 年编写的,预期磁盘速度为数十 MB/s。

相关内容