페이지 캐시를 우회하는 HDD 읽기 벤치마크를 실행하고 있습니다. O_DIRECT 플래그를 설정하고 메모리를 수정했습니다. 이 함수는 파일에서 무작위로 읽기를 시도합니다(lseek64() 사용). 내가 얻은 데이터는 특정 지점(32MB)까지는 괜찮아 보입니다. 아래 데이터(평균)를 살펴보시기 바랍니다. 특히 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
.