手动测试 SSD 读/写

手动测试 SSD 读/写

我正在尝试手动测试 SSD 在 NVMe 上的读写速度。我目前使用的方法是在 SSD 上安装一个文件系统,并以 4KB、32KB、128KB、215KB、1MB、64MB、256MB 和 1GB 的块大小读取/写入 20GB 的文件,同时记录读取/写入的开始时间和完成时间。此过程由 bash 脚本调用。bash 脚本将尝试通过调用以下函数 n 次来运行多个“应用程序”,每次都在后台运行该进程。

while [ $instCnt -le $appInstances ]
    do
    fsrw -w $blocksize /fsmnt/fs${instCnt}/usernumber1/j.j &

以下是 fsrw 可执行文件中的读取函数

bool perform_readop ()
{
// File descriptor.
int32_t fd = -1;

// Function status.
bool status = false;

//Zero read count
int zero_reads = 0;

// Open the file.
fd = open (fname.c_str (), O_RDONLY);

// Verify the file has been opened.
if (fd == -1)
{
    cout << get_datetime_string() << "Read open of " << fname << " failed.  Errno: " 
    << errno << endl;
}
else
{
    // Total bytes read.
    uint64_t rd = 0;

    // Elapsed time.
    struct timeval tv = { 0 };
    get_elapsed_time (&tv);

    // Notify the user that the read test has started.
    cout << get_datetime_string() << "Starting read" << endl;

    while(rd < READ_LIMIT && zero_reads < 10) {
        // Run until it is time for the test to stop.
        ssize_t readsize = read (fd, &buf[0], blocksize);
        if (readsize == -1)
        {
            cout << get_datetime_string << "Read failure.  Errno: " << errno << endl;
            zero_reads = 10;
        }
        else if (readsize == 0)
        {
            cout << get_datetime_string << "Reached EOF." << endl;
            zero_reads++;
        }
        else
        {
            rd += readsize;
        }
    }       
    // Get the elapsed time.
    get_elapsed_time (&tv);

    // Report the number of bytes read.
    cout << get_datetime_string() << "Read " << rd << " bytes in " << tv.tv_sec << "." 
    << tv.tv_usec << " seconds, bytes per second " << bytes_per_second (&tv, rd) << endl;

    // Close the file.
    close (fd);

    // Set the function return status when all read operations have
    // been successful.
    if (zero_reads < 10)
    {
        status = true;
    }
}

  return status;

}

我从其他人之前的工作中移植了这种方法,但我真的不确定这是否是验证 SSD 吞吐量的有效方法。测试结果,尤其是读取操作的结果,并不现实;它们比预期的要高得多。Fio 建议吞吐量应该在 500MB/s 左右,但这次测试记录的写入速度为 1GB+/s,读取速度接近 8GB/s

答案1

不清楚你的问题是什么 - 你似乎在问“为什么我的结果不切实际(为什么它们比 fio 的快?)”。你没有包括你的 fio 作业,所以不可能对此发表任何评论 :-( 我也不知道 fsrw 程序是做什么的。我会尝试看看剩下的内容:

假设我们只有您的程序和内核(这是一种简化)。您的程序发出写入,内核在将它们排队到内部缓冲区中时说“是的,我收到了”,从而允许您的程序继续运行。只有当内部内核缓冲区太满时,您的程序才会阻塞写入,直到有空间接受它。这意味着如果程序在安静的系统上写入“少量”数据,它永远不会等待磁盘为 I/O 提供服务 - 我们通过使用缓冲区将其与磁盘速度分离。显然,这种错觉只能持续一段时间,并且取决于缓冲区有多大、缓冲区有多满等等。

此外,如果有未使用的 RAM,则内核可以使用它来缓存部分磁盘。当我将数据写入磁盘时,如果有空间,我写入的数据不仅会被缓冲并在稍后刷新,而且可以在刷新完成后保留以备以后需要。您可以通过写入文件然后检查空闲空间来看到这种效果,通常您会看到 RAM 数量已经减少,因为该文件的部分内容被保存在缓存中。如果我最终从 Linux 的缓存中读取它,我实现的速度通常接近 RAM 的速度,并且磁盘不会受到影响(如果您知道如何使用 iostat,您会注意到当发生这种情况时它不会报告任何/太多的磁盘 I/O)。

所以:

  • 正常写入 I/O 可以缓冲
  • 正常 I/O 可以被缓存
  • 读取缓存数据比读取未缓存数据快得多
  • 你的读取程序容易受到上一点的影响

注意,这只是一种简化。我还没有介绍预读或文件系统交互等内容,为什么你fsync这样做等等。

此外,内核向磁盘发送的块大小可能与程序提交的大小不同。您可能会向内核发送 16 x 4KB 连续写入,但内核可能会将它们合并在一起,并将单个 64KB 写入发送到磁盘。这在现实生活中通常是有益的,但在进行综合基准测试时您必须注意这一点。

总之,我猜你的结果是“不切实际的”,因为你从 Linux 的缓冲和缓存中受益匪浅。如果你的实际工作量确实是这样的,那么你的 SSD 速度就不是你的瓶颈,更快的磁盘对你没有多大帮助(所以“现实”是一个棘手的词)!通过确保你的数据集大小比系统中的总内存大小大很多倍(至少三倍),或者通过执行无法缓冲或缓存的 I/O,你可以获得更接近 SSD 本身的数字。我无法解释为什么你的速度比 fio 运行得慢,因为任何答案都是高度针对 fio 作业的,而且问题中没有包含任何作业。

答案2

打开 shell 提示符。

使用 dd 命令测量写入速度

dd if=/dev/zero of=/tmp/test1.img bs=1G count=1 oflag=dsync

使用 dd 命令测量延迟

dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 oflag=dsync

dd 命令对于找出简单的顺序 I/O 性能很有用。

使用 dd 命令测试读取速度

为了获得准确的读取测试数据,请首先通过运行以下命令在测试前丢弃缓存:

flush
echo 3 | sudo tee /proc/sys/vm/drop_caches

然后运行以下命令(创建 laptop.bin 之后):

dd if=/dev/zero of=/tmp/laptop.bin bs=1G count=1 oflag=direct

相关内容