31
Merge with reverse 고고 고고고 고고고고고 20143106 고고고

Merge revesed

Embed Size (px)

Citation preview

Page 1: Merge revesed

Merge with reverse고급 시스템 프로그래밍

20143106 진희상

Page 2: Merge revesed

목록 1. 과제 목표 및 예시 2. 과제 시작 전 고려한 사항 3. 시도해 본 것 4. 프로그램 결과 5. 성능 비교 결과 6. 의문사항

Page 3: Merge revesed

1. 과제 목표 및 예시

Page 4: Merge revesed

과제 목표 과제목표– 두 ( 큰 ) 파일을만들고– 그 파일을 line-by-line 으로 reverse/merge 하는 – 성능좋은 프로그램만들기 성능은 ?

– 성능 =( 최종버전실행시간 )/(Template 실행시간 ) 자신의 raspberry PI 에서 비교– 실행 시간 = merge 프로그램이 두 file 을 reverse/merge 하여 두 배 크기의 file 을 만드는데 걸린 시간 , 5 번 실행 평균 – 입력 File : 100MB 의

text file (gen.c 로 만들어진 것 ) 출력파일 : 두입력파일의각라인을 string 을 reverse 하고 , 두 파일을 한 줄씩 번갈아가며 쓴 file

Page 5: Merge revesed

과제 예시파일 A 와 B 를 한줄 씩 번갈아 가며 , Reverse 시켜서 파일 C 에 쓴다 .( 단 , 파일 A 가 끝났을 때는 , 파일 B만 쓴다 .)

Page 6: Merge revesed

2. 과제 시작 전 고려한 사항

Page 7: Merge revesed

과제 시작 전 고려한 사항 1. 파일 접근 함수 중 f 가 있는 것과 없는 것의 차이는 무엇인가 ?

fopen/fread/fwrite/fclose <-> open/read/write/close 2. mmap 은 무엇인가 ? 사용법은 ? 3. fopen/fread/fwrite/fclose <-> open/read/write/close <-> mmap중 무엇이 가장 빠른가 ? 4. reverse 는 어떻게 해야 빠른가 ?

Page 8: Merge revesed

과제 시작 전 고려한 사항 1. 파일 접근 함수 중 f 가 있는 것과 없는 것의 차이는 무엇인가 ?

fopen/fread/fwrite/fclose <-> open/read/write/close fread 함수는 오로지 파일만 읽을 수 있다 . 그렇기 때문에 \n -> \r\n 으로 바꾸는 등 파일에 적합한 작업을 한다 . 그리고스트림이라는 버퍼를 생성해 , 파일에 접근할 때 한번에 많은 부분을 가져와놓고스트림에서 필요만 만큼만 유저가 가져다 쓰는 방식이다 . 반대로 read 함수는 파일 이외의 IO 장치들을 파일 처럼 읽을 수 있다 .

Read 함수가 호출 될 때마다 명시된 부분 만큼만 읽는다 .

또한 fread 안에 read 가 있기때문에 실질적으로 IO 에 접근하는 함수는 read이다 .

Page 9: Merge revesed

과제 시작 전 고려한 사항 2. mmap 은 무엇인가 ? Mmap 은 하드에 있는 파일을 메모리에 그대로 올려서 사용자가 직접 사용할 수 있도록 맵핑시켜 주는 강력한 함수이다 .중간과정에서 버퍼를 사용하지 않기 때문에 기본적으로 빠르다 .

Page 10: Merge revesed

과제 시작 전 고려한 사항 3. fopen/fread/fwrite/fclose <-> open/read/write/close <-> mmap중 무엇이 가장 빠른가 ? 버퍼를 적절하게 사용하면 fopen 과 open 은 속도가 비슷하다 . 기본적으로 Mmap 이 가장 빠르다 . Which is fastest: read, fread, ifstream or mmap?

http://lemire.me/blog/2012/06/26/which-is-fastest-read-fread-ifstream-or-mmap/

Page 11: Merge revesed

과제 시작 전 고려한 사항 4. reverse 는 어떻게 해야 빠른가 ? 구글링 한다 . VS 직접 만든다 .

Page 12: Merge revesed

3. 시도해 본 것

Page 13: Merge revesed

시도해 본 것 1. fgetc 대신 read 사용 2. fputc 대신 write 사용 3. mmap 사용 4. reverse 함수 5. reverse 를 위한 버퍼 제거

Page 14: Merge revesed

1. fgetc 대신 read 사용 Fgetc 는 파일에서 한 문자씩 읽는다 . 파일 끝에 도달할 때까지 한 문자씩 읽는 방식을 사용 . read 는 한번에 많은 문자를 읽는다 . 그러나 그만한 문자를 읽어 들일 버퍼가 필요하다 .

결과 Read 를 사용했을 때의 속도가 더 빨랐다 .

Page 15: Merge revesed

2. fputc 대신 write 사용 Fputc 는 파일에 한 문자씩 쓴다 .

Fgetc 로 한 문자씩 받을 때 마다 파일에 바로바로 썼다 . 버퍼에 읽어 들인 문자열을 write 로 한번에 썼다 .

결과 write 를 사용했을 때의 속도가 더 빨랐다 .

Page 16: Merge revesed

3. mmap 사용 - 1

Mmap 이 fputc, fgetc, read, write 보다 정말 빠를까 ?에 대한 실험을 먼저 하였다 . 파일 두개를 번갈아 쓰는 것과 reverse 하는 것은 생각하지 않고우선 단순히 100MB 파일을 복사하는데 얼마나 걸릴 지를 실험하였다 . mmap() 을 사용해 100MB 파일 복사를 했을떄 , 0.13sec 가 걸렸다 .그에 반해 기존의 merge.c template 은 35sec 가 걸렸다 .

( 아두이노가 아닌 맥북환경 ) 인터넷 검색정보도 mmap 이 가장 빠르다하였고이론적으로 생각해도 버퍼를 사용하는 다른 함수보다는

mmap 가 가장 빠를 것이라고 생각했다 . 그리고 100MB 0.13sec 를 확인한 순간 mmap 를 사용하겠다고 결정했다 .

Page 17: Merge revesed

3. mmap 사용 - 2

mmap 을 사용하여 파일출력을 하는데“ bus error: 10” 에러가 나타났다 .

원인 Write, fputs, fprintf 를 사용하여 파일쓰기를 할 경우에는데이터를 씀에 따라서 출력파일의 용량이 자동으로 그에 맞추어 커지지만 , Mmap 은 단순히 메모리 맵핑만을 해주기 때문에 기존파일의 용량을자동으로 증가시켜주지 않는다 . 즉 , 200MB 의 f_out 파일을 미리 만들어야한다 .

해결 Ftruncate 를 사용하여 , 파일의 크기를 200MB 증가시킨 후 파일 출력을 하였다 .

Page 18: Merge revesed

3. mmap 사용 - 3

mmap 을 사용할 때는 맵핑할 사이즈 정보가 필요하다 .기존에는 입력파일은 100MB, 출력파일은 200MB 로 하드코딩하였지만 , fseek, ftell 을 이용하여 , 입력파일들의 용량을 측정하여맵핑할 사이즈 정보를 결정하였다 .

Page 19: Merge revesed

4. reverse 함수 인터넷 검색을 해보면 , 좋은 퍼포먼스의 reverse 함수를 쉽게 찾을 수있다 .하지만 , 이번 과제에서는 굳이 reverse 함수를 사용할 필요가 없었다 . 왜냐하면 reverse 함수는 기존의 배열의 순서를 바꾸는 것이기 때문이다 .하지만 , 이번 과제는 단순히 거꾸로 파일출력만 하면 되기때문에배열을 뒤에서부터 거꾸로 읽어서 쓰면 된다 . 그래서 reverse 함수를 따로 사용하지 않았다 .

Page 20: Merge revesed

4. reverse 함수 - 구현 File_in 에서 한 문자씩 읽어서 버퍼에 쓰다가‘ \n’ 을 만나면 buffer 에서 뒤에서부터 한문자씩 읽어서 File_out 에 쓴다 .

1 2 3 4 \n 5 6 7 8 … FILE IN

1 2 3 4 \n BUFFER

4 3 2 1 FILE OUT

Page 21: Merge revesed

5. reverse 를 위한 버퍼 제거 4 단계에서 완성된 프로그램의 reverse_merge 프로그램이 실행속도가약 35sec 가 걸렸다 .( 라즈베리 파이 기준 ) 실행속도를 더 줄일 수 없을까 생각하다가 버퍼를 사용하지 않기 위해 mmap 을 사용했는데 , 결국 reverse 에서 버퍼를 사용한게 문제이지 않을까하고 생각했다 . 그래서 이번에는 reverse 를 위한 버퍼를 없애고 ,오로지 file_in 과 file_out 의 포인터로만 reverse 를 구현했다 . 그 결과 35sec 의 실행시간이 20sec 로 줄었다 .

Page 22: Merge revesed

5. reverse 함수 ( 버퍼제거 )- 구현 File_in 에서 한 문자씩 읽어서 포인터를 증가시키다‘ \n’ 을 만나면 뒤에서부터 다시 한문자씩 읽어서 File_out 에 쓴다 .

1 2 3 4 \n 5 6 7 8 … FILE IN

4 3 2 1 FILE OUT

Page 23: Merge revesed

4. 프로그램 결과

Page 24: Merge revesed

최종 프로그램 https://github.com/HeesangJin/adv-sys-programming

결과 (왼쪽 : 최종 프로그램 결과 , 오른쪽 : template 결과 )

Page 25: Merge revesed

5. 성능 비교 결과

Page 26: Merge revesed

성능 비교 결과 (template)

Page 27: Merge revesed

성능 비교 결과 (my program)

Page 28: Merge revesed

성능 비교 결과(단위 : sec) template My program

1회 104.6 11.92회 96.1 18.53회 101.7 18.34회 102.5 22.55회 103.8 21.6평균 101.74 18.56성능 = ( 최종버전실행시간 )/(Template 실행시간 )

= 101.74 / 18.56= 0.182

Page 29: Merge revesed

6. 의문사항

Page 30: Merge revesed

의문사항 프로그램을 5 번연속 실행할 때중간중간에 30초 정도 쉬고 실행하면 실행시간이 20초대로 일정한데 , 쉬지않고 바로 실행하면 실행시간이 10초~50초로 뒤죽박죽하다 .

=> 왜 그럴까 ? 맥북에서는 템플릿 프로그램 35sec, 내 프로그램 0.8sec 로 성능차이가 엄청 났는데라즈베리파이에서 할 땐 , 템플릿 프로그램 100sec, 내 프로그램 20sec 로맥북에서 할 때보다 내 프로그램의 성능이 비교적 확연히 줄었다 .

=> MMAP() 이 메모리크기에 따라 성능차이가 나는 것일까 ??

Page 31: Merge revesed