Sunday, January 07, 2007
C언어] CRC32 구하기 버전업 (코드 최적화): CRC32.cpp
예전에 올린 CRC 계산 소스에서 불합리한 부분을 고쳤습니다. makeCRCtable() 함수로 테이블을 계속 만들게 되어 있었는데, 마조리카님께서 지적해 주신대로 한번만 만들게 했습니다.
2번째 소스 파일인 CRC32.cpp 만 업데이트하면 됩니다. 다른 부분은 여기에 있는 것과 같습니다: ▶▶ [C언어] 비주얼C로, 파일의 CRC32 값 구하기 (빠르고 메모리 점유 없이)
파일명: CRC32.cpp
※ 아래 박스 클릭 후, 키보드 화살표 키로 좌우 스크롤 가능함
그런데 저의 경우, 최적화한 소스와, 최적화하지 않은 소스의 속도 차이는 전혀 없더군요.
비주얼C 컴파일러의 속도 최적화 옵션을 켠 상태이기 때문에, 비주얼C가 알아서, 중복되는 코드를 제거하고 자동으로 최적화해 준 것 같습니다.
속도가 느렸다면, 제가 눈치채고 고쳤을 텐데, 그렇지 않아서 제가 최적화를 간과하고 말았습니다^^;
2번째 소스 파일인 CRC32.cpp 만 업데이트하면 됩니다. 다른 부분은 여기에 있는 것과 같습니다: ▶▶ [C언어] 비주얼C로, 파일의 CRC32 값 구하기 (빠르고 메모리 점유 없이)
업데이트할, 새 버전 소스 파일
파일명: CRC32.cpp
※ 아래 박스 클릭 후, 키보드 화살표 키로 좌우 스크롤 가능함
unsigned long getFileCRC(FILE *);
unsigned long calcCRC (const unsigned char *, signed long, unsigned long, unsigned long *);
void makeCRCtable(unsigned long *, unsigned long);
unsigned long getFileCRC(FILE *s) {
unsigned char buf [32768];
unsigned long CRC = 0;
unsigned long table[256];
size_t len;
makeCRCtable(table, 0xEDB88320);
while ( (len = fread(buf, 1, sizeof(buf), s)) != NULL )
CRC = calcCRC(buf, (unsigned long) len, CRC, table);
return CRC;
}
unsigned long calcCRC(const unsigned char *mem, signed long size, unsigned long CRC, unsigned long *table) {
CRC = ~CRC;
while(size--)
CRC = table[(CRC ^ *(mem++)) & 0xFF] ^ (CRC >> 8);
return ~CRC;
}
void makeCRCtable(unsigned long *table, unsigned long id) {
unsigned long i, j, k;
for(i = 0; i < 256; ++i) {
k = i;
for(j = 0; j < 8; ++j) {
if (k & 1) k = (k >> 1) ^ id;
else k >>= 1;
}
table[i] = k;
}
}
unsigned long calcCRC (const unsigned char *, signed long, unsigned long, unsigned long *);
void makeCRCtable(unsigned long *, unsigned long);
unsigned long getFileCRC(FILE *s) {
unsigned char buf [32768];
unsigned long CRC = 0;
unsigned long table[256];
size_t len;
makeCRCtable(table, 0xEDB88320);
while ( (len = fread(buf, 1, sizeof(buf), s)) != NULL )
CRC = calcCRC(buf, (unsigned long) len, CRC, table);
return CRC;
}
unsigned long calcCRC(const unsigned char *mem, signed long size, unsigned long CRC, unsigned long *table) {
CRC = ~CRC;
while(size--)
CRC = table[(CRC ^ *(mem++)) & 0xFF] ^ (CRC >> 8);
return ~CRC;
}
void makeCRCtable(unsigned long *table, unsigned long id) {
unsigned long i, j, k;
for(i = 0; i < 256; ++i) {
k = i;
for(j = 0; j < 8; ++j) {
if (k & 1) k = (k >> 1) ^ id;
else k >>= 1;
}
table[i] = k;
}
}
그런데 저의 경우, 최적화한 소스와, 최적화하지 않은 소스의 속도 차이는 전혀 없더군요.
비주얼C 컴파일러의 속도 최적화 옵션을 켠 상태이기 때문에, 비주얼C가 알아서, 중복되는 코드를 제거하고 자동으로 최적화해 준 것 같습니다.
속도가 느렸다면, 제가 눈치채고 고쳤을 텐데, 그렇지 않아서 제가 최적화를 간과하고 말았습니다^^;
tag: cpp
C언어 | C/C++ (Visual C++)
질문이 있는데요. 기가단위 파일을 사용해서
그냥 속도를 빠르게 하기위하여 바이트 읽는 크기를 1메가 정도로 그냥 사용해도 되는건가요??
위의 소스 코드에서는 32768 바이트씩 파일을 읽습니다.
제가 4기가짜리 파일로 테스트해 본 결과,
버퍼 크기를 100메가쯤으로 늘린다고 해도 속도가 전혀 빨라지지 않았습니다.
그러나 초대용량 파일을 주로 다루신다면, 버퍼 크기를 수십 메가쯤으로 늘리는 것도 좋을 듯합니다.
결론은, 그냥 사용하셔도 괜찮습니다. 속도 차이를 체감할 수 없습니다.
<< Home