사용 sendfile()에 사본을 파일이 스레드 또는 다른 효율적인 파일을 복사방법
-
21-12-2019 - |
문제
내가 사용하는 리눅스 시스템호출 sendfile()
파일을 복사를 사용하여 스레드입니다.
나를 최적화에 관심이 이러한 부분의 코드:
fseek(fin, size * (number) / MAX_THREADS, SEEK_SET);
fseek(fout, size * (number) / MAX_THREADS, SEEK_SET);
/* ... */
fwrite(buff, 1, len, fout);
코드:
void* FileOperate::FileCpThread::threadCp(void *param)
{
Info *ft = (Info *)param;
FILE *fin = fopen(ft->fromfile, "r+");
FILE *fout = fopen(ft->tofile, "w+");
int size = getFileSize(ft->fromfile);
int number = ft->num;
fseek(fin, size * (number) / MAX_THREADS, SEEK_SET);
fseek(fout, size * (number) / MAX_THREADS, SEEK_SET);
char buff[1024] = {'\0'};
int len = 0;
int total = 0;
while((len = fread(buff, 1, sizeof(buff), fin)) > 0)
{
fwrite(buff, 1, len, fout);
total += len;
if(total > size/MAX_THREADS)
{
break;
}
}
fclose(fin);
fclose(fout);
}
해결책
파일이 복사되지 않은 CPU;었다면 당신이 찾을 가능성이 제한 커널 수준에서 아무것도 당신은에서 할 수 있는 사용자 leve 것이 병렬화하다.
이러한"개선"에서 수행되는 기계 드라이브는 것입니다 사실 저하 의 처리량을 자랑합니다.당신이 시간을 낭비하 찾을 따라 파일 읽기와 쓰기의습니다.
는 경우는 파일이 오랫동안 당신은하지 않는 기대를 필요로 읽거나 기록 데이터 언제나 빨리,그것은 유혹 될 수 있을 사용하여 O_DIRECT
국기에 열려 있습니다.는 나쁜 생각 때문에, O_DIRECT
API 은 기본적으로 에 의해 깨진 디자인.
대신 사용해야 합니다 posix_fadvise
에 대 파일 POSIX_FADV_SEQUENTIAL 및 POSIX_FADV_NOREUSE 플래그입니다.후 쓰기(또는 sendfile)호출이 완료되면 알려주는 데이터가 더 이상 필요하지 않습니 패스 POSIX_FADV_DONTNEED.는 방법으로 페이지를 캐쉬하려는 목적으로만 사용됩 정도를 유지하는 데 필요한 데이터 흐르는,그리고 페이지를 재활용 할로 데이터 소(디스크에 기록).
이 sendfile
지 않습 밀어 파일 데이터를 통해 사용자 공간,그래서 그것은 더 이완 압력의 일부 메모리에서 프로세서 캐시입니다.대만 다른 현명한 개선할 수 있습을 위해 파일의 복사를 의지 않은 장치마다 다릅니다.
선택하는 합리적인 덩어리이기도 바람직하다.주어진 현대적 드라이브 밀어 통해 100Mbytes/s,할 수 있는 푸시 메가바이트에 시간,그리고 항상 여러 개의 4096 바이트 페이지 크기에 따라서 (4096*256)
제작 크기 덩어리를 처리하는 단일 sendfile
나 read
/write
호출합니다.
읽어 병렬화로,당신은 제안에만 의미가에 RAID0 볼륨 및 경우에만 모두 입력 및 출력 파일에 걸쳐 물리적 디스크가 있습니다.할 수 있는 하나의 스레드당 낮은 수의 소스 및 대상 볼륨을 실제 디스크 벌리에 의해 파일입니다.는 필요하지 않으면 사용하는 비동기 파일 I/O.로 async I/O 당신이 필요하지 않을 것은 더 이상 하나의 스레드는 어쨌든,특히지 않는 경우에 덩어리가 크기가 큰(메가바이트+)와의 단일드 대기 시간을 벌금을 무시할 수 있습니다.
아무 의미가 없을 위한 병렬화의 단일 파일에서 복사 Ssd 지 않는 한,당신은에 아주 이상한 시스템은 실제로.