C언어] CRC32 구하기 버전업 (코드 최적화): CRC32.cpp
Sunday, January 07, 2007
스폰서 링크예전에 올린 CRC 계산 소스에서 불합리한 부분을 고쳤습니다. makeCRCtable() 함수로 테이블을 계속 만들게 되어 있었는데, 마조리카님께서 지적해 주신대로 한번만 만들게 했습니다.
2번째 소스 파일인 CRC32.cpp 만 업데이트하면 됩니다. 다른 부분은 여기에 있는 것과 같습니다: ▶▶ [C언어] 비주얼C로, 파일의 CRC32 값 구하기 (빠르고 메모리 점유 없이)
파일명: CRC32.cpp
그런데 저의 경우, 최적화한 소스와, 최적화하지 않은 소스의 속도 차이는 전혀 없더군요.
비주얼C 컴파일러의 속도 최적화 옵션을 켠 상태이기 때문에, 비주얼C가 알아서, 중복되는 코드를 제거하고 자동으로 최적화해 준 것 같습니다.
속도가 느렸다면, 제가 눈치채고 고쳤을 텐데, 그렇지 않아서 제가 최적화를 간과하고 말았습니다^^;
☞ C/C++ (VC++)
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가 알아서, 중복되는 코드를 제거하고 자동으로 최적화해 준 것 같습니다.
속도가 느렸다면, 제가 눈치채고 고쳤을 텐데, 그렇지 않아서 제가 최적화를 간과하고 말았습니다^^;
☞ C/C++ (VC++)
질문이 있는데요. 기가단위 파일을 사용해서
그냥 속도를 빠르게 하기위하여 바이트 읽는 크기를 1메가 정도로 그냥 사용해도 되는건가요??
위의 소스 코드에서는 32768 바이트씩 파일을 읽습니다.
제가 4기가짜리 파일로 테스트해 본 결과,
버퍼 크기를 100메가쯤으로 늘린다고 해도 속도가 전혀 빨라지지 않았습니다.
그러나 초대용량 파일을 주로 다루신다면, 버퍼 크기를 수십 메가쯤으로 늘리는 것도 좋을 듯합니다.
결론은, 그냥 사용하셔도 괜찮습니다. 속도 차이를 체감할 수 없습니다.
Post a Comment
<< Home