저는 여러 데이터 포인트를 큰 파일로 직렬화하는 Tensorflow의 TFRecords 형식을 사용하고 있습니다. 여기서 일반적인 값은 데이터 포인트당 10KB, 대용량 파일당 데이터 포인트 10,000개, 대용량 파일의 경우 약 100MB입니다. TFRecord는 일반적으로 한 번만 작성되며 추가되지 않습니다. 나생각하다이는 그들이 널리 퍼지지 않을 것임을 의미합니다.
나는 TFRecords가 Google의 내부 RecordIO 형식을 기반으로 한다고 생각합니다.
일반적으로 사람들은 Ubuntu 18.04 또는 20.04에서 Tensorflow 및 TFRecords를 실행하는데, 이는 일반적으로 ext4 파일 시스템이라고 생각합니다.
일반적으로 딥 러닝 엔지니어는 SSD/NVME 디스크에서 실행됩니다. 자기 회전 플래터의 증분 비용은 GPU 자체의 막대한 비용에 비하면 중요하지 않습니다.
질문 1:
ext4 파일 시스템에서 특정 데이터 포인트가 파일의 9,000,000바이트라는 것을 알고 있는 경우 해당 위치를 조회하고 일정한 시간에 해당 데이터 포인트를 읽을 수 있습니까? 내가 의미하는 상수 시간은 검색 깊이의 함수와 같습니다. 전체 파일 크기에 미치는 영향은 걱정하지 않습니다.
이것이 사실이라면 ext4 파일 시스템의 모든 파일에는 조회 위치를 디스크 섹터에 매핑하는 일종의 조회 테이블/인덱스가 있다는 의미입니다.
나는 수십 년 동안 파일 시스템을 연구하지 않았지만 FAT 파일 시스템이 연결 목록이었다는 것을 기억하는 것 같습니다. 다음 디스크 섹터가 무엇인지 알기 위해 하나의 디스크 섹터를 읽어야 했습니다. 이는 파일에서 9,000,000바이트를 찾으려면 처음 8,999,999바이트부터 모든 디스크 섹터를 읽어야 함을 의미합니다. 예를 들어, 탐색 시간은 탐색의 "깊이"에 따라 선형적으로 확장됩니다. 나는 ext4가 선형이 아닌 상수 시간이기를 원합니다.
질문 2:
나의 궁극적인 목표는 TFRecord에 대한 무작위 액세스를 수행하는 것입니다. TFRecord는 무작위 액세스가 아닌 직렬 읽기용으로 설계되었습니다. 그 이유는 자기 회전 플래터의 읽기 속도를 최적화하는 것과 관련이 있다고 생각하기 때문입니다.
탐색 기능이 일정한 시간(탐색 깊이에 따라)인지 여부에 관계없이 ext4 파일 시스템의 대용량 파일에 대한 무작위 액세스가 "충분히 빠릅니까"? 솔직히 말해서 충분히 빠른 것이 무엇인지는 정확히 알 수 없지만 단순화를 위해 매우 빠른 딥 러닝 모델이 초당 10,000개의 데이터 포인트를 가져올 수 있다고 가정해 보겠습니다. 여기서 각 데이터 포인트는 약 10KB입니다. 대용량 파일에서 무작위로 추출하여 추출합니다.
답변1
파일이 디스크에서 조각화되지 않은 경우일 수 있습니다. 그러나 시간이 엄격히 일정하다면 그것은 중요하지 않을 수도 있습니다.
ext2 및 ext3은 레벨 1~4의 트리에 데이터 블록의 위치를 저장하므로 조회는 일정한 시간이 될 수 없습니다. 또한 트리의 블록은 원칙적으로 파일 시스템의 어느 위치에나 위치할 수 있으므로 일부 디스크 검색이 필요할 수 있습니다.
ext4는 여러 연속 데이터 블록을 설명하는 범위 트리를 저장합니다. 따라서 파일에 범위가 하나만 있는 것으로 알려진 경우 검색 시간은 일정합니다. 하지만 조각화된 경우(또는 128MiB보다 크거나 여러 범위가 필요한 경우)에는 그렇지 않습니다.
(원천:https://www.kernel.org/doc/html/latest/filesystems/ext4/dynamic.html#the-contents-of-inode-i-block)
찾는 것이 더 걱정될 수도 있지만충분히 빠르다, 만약 그랬다면일정한 시간. 어쨌든 트리가 너무 깊지 않기 때문에 이것은 더 쉬운 대상이며 동일한 파일에 반복적으로 액세스하면 모두 메모리에 빠르게 로드되어 디스크 검색이 제거됩니다(SSD에서는 그렇지 않음). , 그러나 어쨌든). 또한 액세스당 시스템 호출 오버헤드가 있는데, 각 읽기/쓰기 전에 검색을 수행하면 3배가 됩니다. 하지만 내 생각에는 이 문제를 완화할 수 있는 좀 더 발전된 시스템 호출이 있다고 생각합니다.
FAT 파일 시스템은 연결 목록입니다. 다음 디스크 섹터가 무엇인지 알려면 디스크 섹터를 읽어야 합니다. 이는 파일에서 9,000,000바이트를 찾으려면 처음 8,999,999바이트부터 모든 디스크 섹터를 읽어야 함을 의미합니다. 예를 들어, 탐색 시간은 탐색의 "깊이"에 따라 선형적으로 확장됩니다.
FAT 파일 시스템에는 연결된 목록을 형성하는 블록 포인터 테이블(FAT 테이블)이 있습니다. 데이터 블록 자체가 아닙니다. 따라서 예를 들어 블록 크기가 4kB인 경우 9000000 / 4096 ~= 2000개의 포인터만 읽어야 하며 이는 몇 kB의 가치가 있습니다. 하지만 여전히 연결된 목록이고 이를 반복하려면 조회 위치에 비례하는 많은 단계가 필요합니다(fs 드라이버에 이를 줄이는 현명한 기능이 없는 경우). 그러나 FAT 테이블은 연속적이며 메모리에 있을 수도 있으므로 디스크 조회가 필요하지 않습니다.
여기서 일반적인 값은 데이터 포인트당 10KB, 대용량 파일당 데이터 포인트 10,000개, 대용량 파일의 경우 약 100MB입니다.
매우 빠른 딥 러닝 모델이 초당 10,000개의 데이터 포인트를 추출할 수 있다고 가정해 보겠습니다. 여기서 각 데이터 포인트는 약 10KB이며 대용량 파일에서 무작위로 추출됩니다.
100MB 파일은 메모리 전체에 쉽게 들어갈 수 있으며(여러 번), 이를 유지하면 검색에 대한 시스템 호출 오버헤드도 제거됩니다. 읽기만 하면 그게 다입니다.
글을 쓰는 경우에도 특별한 주의 없이 모든 쓰기 작업이 즉시 디스크 플래시에 도달하는 것은 아니므로 전체 프로세스가 느려질 수 있다는 점에 유의하십시오. (적어도 fsync()
매번 호출해야 하며 드라이브가 사용자를 속이지 않을 것이라고 믿어야 합니다.) 파일을 메모리에 저장하고 가끔씩 수동으로 다시 쓰거나 메모리에 매핑 mmap()
하고 msync()
쓰기 요청을 호출할 수 있습니다. 때때로 다시.