read() 随机打开 O_DIRECT 标志的文件,在 32 MB 文件大小上会严重影响性能吗?

read() 随机打开 O_DIRECT 标志的文件,在 32 MB 文件大小上会严重影响性能吗?

我正在运行绕过页面缓存的 HDD 读取基准测试。我已经设置了 O_DIRECT 标志并修改了我的内存。此函数尝试在文件中随机读取(使用 lseek64())。我得到的数据在某个点(32 MB)之前看起来都很好。请看下面的数据(平均值): 我特别想知道为什么我在32MB之后会有这么大的跳跃?我使用 Ubuntu 16.04 文件系统 ext4。

我真的很感激对此的一些帮助。谢谢。

KB      TIME
32      11.2452
64      22.3882
128     45.3915
256     89.6025
512     12.655
1024    402.332
2048    759.456
4096    1512.83
8192    2999.54
16384   5988.16
32768   **85358.8**





double readFileRan(std::string name, unsigned long bytes) {
   Time t;

   int ID = open(name.c_str(), O_RDONLY | O_DIRECT);

   sync();

   if ( ID == -1) {
       std::cout << "can't open input file!" << std::endl;
       return 0;
   }

   unsigned long reads = bytes / 512;
   std::vector<unsigned long> offsets;
   for(unsigned long i = 0; i < reads; i++) {
      offsets.push_back((rand() % reads) * 512);
   }

   int BLKSIZE = 512;
   char* sector = (char*)memalign(BLKSIZE, BLKSIZE); //size of physical   sector
   unsigned long numRead = 0;
   unsigned long i = 0;
   off64_t result = 10;

   unsigned long long start = t.start();
   while(i <= reads)  {
      result = lseek64(ID, offsets[i] ,SEEK_SET);
      numRead = read(ID, sector, 512);
      i = i + 1;
   }
   unsigned long long end = t.end();
   close(ID);

   unsigned long long total = end - start;
   double mili = t.convertCyclesToSec(total);

   std::cout << mili << std::endl;
   return mili;
}

答案1

读取扇区的时间取决于尝试读取时驱动器的旋转角度,并且您的样本量太小,无法避免此随机过程的统计波动。每个扇区平均只读一次。当bytes很大并且您要采集大量样本时,这很好,但当bytes很小时,那就不太好了。为了获得更有趣的数据,您应该始终读取固定数量的扇区,而与 的大小无关bytes

在某些时候,当超过柱面大小时,访问时间预计会出现跳跃bytes,并且磁头必须从磁道移动到磁道,而不是仅仅等待正确的扇区飞过(这也需要时间,但时间较少)。但是,当读取原始分区而不是通过文件系统(可以自由地将文件扇区非线性映射到设备扇区)时,可以更好地看到这种效果。

当然,现代磁盘的柱面尺寸是可变的,因为与靠近主轴的较短内磁道相比,较长的外磁道可以容纳更多的扇区。

尝试测量所有这些会变得更加复杂,因为您可能在磁盘本身上有一个小的内存缓存,并且不能单独使用O_DIRECT.

相关内容