read () aleatoriamente um arquivo com o sinalizador O_DIRECT ativado, obtendo um desempenho sério em 32 MB?

0

Estou executando uma referência de leitura de HDD que ignora o cache de páginas. Eu configurei a sinalização O_DIRECT e limpei minha memória. Esta função tenta uma leitura aleatória dentro de um arquivo (lseek64 () usado). Os dados que estou recebendo parece bem até certo ponto (32 MB). Por favor, veja os dados abaixo (médias): Em particular, gostaria de saber por que tenho um salto tão grande depois de 32 MB? Eu uso o Ubuntu 16.04 File System ext4.

Eu realmente aprecio alguma ajuda sobre isso. Obrigado.

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;
}
    
por Illia 02.12.2016 / 01:49

1 resposta

1

O tempo para ler um setor depende do ângulo de rotação do disco quando você tenta ler, e seu tamanho de amostra é muito pequeno para evitar flutuações estatísticas desse processo aleatório. Você está lendo todos os setores apenas uma vez, em média. Isso é bom quando bytes é grande e você está obtendo muitas amostras, mas não é tão bom quando bytes é pequeno. Para obter dados mais interessantes, você deve sempre ler um grande número fixo de setores, independentemente da magnitude de bytes .

Em algum ponto, pode-se esperar um salto no tempo de acesso, quando bytes excede o tamanho de um cilindro, e o cabeçote tem que se mover de pista em trilha, em vez de apenas esperar que o setor correto voe. (o que também leva tempo, mas menos tempo). Mas esse efeito pode ser melhor visto quando se lê uma partição bruta, em vez de um sistema de arquivos (que é livre para mapear os setores de arquivos não linearmente para os setores de dispositivos).

Os tamanhos dos cilindros dos discos modernos são, é claro, variáveis, já que mais setores podem se encaixar nos trilhos mais longos do que nos trilhos internos menores, mais próximos do eixo.

Tentar medir tudo isso é ainda mais complicado pelo fato de que você provavelmente tem um pequeno cache de memória no próprio disco, que não é desativado somente usando O_DIRECT .

    
por 02.12.2016 / 02:39