참고
- B형에 필요한 최적화 코드 (1) (register 변수)
- 함수의 매개변수와 배열의 register 속도 비교
- Visual Studio LNK1168: 쓰기용으로 열 수 없습니다 해결방법
변수 외에도 함수의 매개변수나 배열에 register 키워드를 추가하면 속도 향상 효과를 볼 수 있다.
특히, 자주 사용하는 배열일수록 효과적이다.
매개변수 register
같은 동작을 하는 test1과 test2 함수가 있다.
test2는 parameter에 register를 추가하였다.
char myMap[MAX][MAX];
void test1(int a)
{
int b = 3;
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
{
sum += a;
sum += b;
}
}
void test2(register int a)
{
int b = 3;
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
{
sum += a;
sum += b;
}
}
SW EXPERT 아카데미에서 위의 함수를 테스트하면, register 키워드가 있는 경우 속도가 더 빠르다.
테스트 코드는 아래와 같다.
#include <stdio.h>
#include <time.h>
#define MAX (10000)
char myMap[MAX][MAX];
void test1(int a)
{
int b = 3;
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
{
sum += a;
sum += b;
}
}
void test2(int a)
{
int b = 3;
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
{
sum += a;
sum += b;
}
}
int main()
{
int TESTCASE = 5;
{
int TIME = 0;
/* Timer on */
clock_t start = clock();
/* 실행 코드 */
for (int tc = 1; tc <= TESTCASE; tc++)
{
test1(3);
}
/* Timer off */
TIME += ((int)clock() - start) / (CLOCKS_PER_SEC / 1000);
printf("\nNO REGISTER TIME : %d ms\n", TIME); /* ms 단위로 출력 */
}
{
int TIME = 0;
/* Timer on */
clock_t start = clock();
/* 실행 코드 */
for (int tc = 1; tc <= TESTCASE; tc++)
{
test2(3);
}
/* Timer off */
TIME += ((int)clock() - start) / (CLOCKS_PER_SEC / 1000);
printf(" REGISTER TIME : %d ms\n", TIME); /* ms 단위로 출력 */
}
return 0;
}
배열 register
매개변수가 배열인 경우에도 register를 추가할 수 있다.
매개변수에서 배열은 실제로 포인터이기 때문이다.
위와 마찬가지로 테스트 코드를 실행하면 속도 향상 효과가 있는 것을 알 수 있다.
#include <stdio.h>
#include <time.h>
#define MAX (10000)
char myMap[MAX][MAX];
void test1(char map[MAX][MAX])
{
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
sum += map[r][c];
}
void test2(register char map[MAX][MAX])
{
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
sum += map[r][c];
}
int main()
{
int TESTCASE = 10;
{
int TIME = 0;
/* Timer on */
clock_t start = clock();
/* 실행 코드 */
for (int tc = 1; tc <= TESTCASE; tc++)
{
test1(myMap);
}
/* Timer off */
TIME += ((int)clock() - start) / (CLOCKS_PER_SEC / 1000);
printf("\nNO REGISTER TIME : %d ms\n", TIME); /* ms 단위로 출력 */
}
{
int TIME = 0;
/* Timer on */
clock_t start = clock();
/* 실행 코드 */
for (int tc = 1; tc <= TESTCASE; tc++)
{
test2(myMap);
}
/* Timer off */
TIME += ((int)clock() - start) / (CLOCKS_PER_SEC / 1000);
printf(" REGISTER TIME : %d ms\n", TIME); /* ms 단위로 출력 */
}
return 0;
}
전역 배열 register
전역 배열 myMap에 대해 아래와 같이 test1, test2는 속도 면에서 큰 차이가 없다.
#define MAX (10000)
char myMap[MAX][MAX];
void test1()
{
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
sum += myMap[r][c];
}
void test2()
{
char (*map)[10000] = myMap;
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
sum += map[r][c];
}
이제 test2에는 register를 이용해 배열을 포인터에 할당해보자.
void test2()
{
register char (*map)[10000] = myMap;
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
sum += map[r][c];
}
전역변수로 선언된 배열을 register로 다시 할당한 후, 코드를 실행하면 속도가 향상되는 것을 알 수 있다.
테스트 코드는 다음과 같다.
#include <stdio.h>
#include <time.h>
#define MAX (10000)
char myMap[MAX][MAX];
void test1()
{
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
sum += myMap[r][c];
}
void test2()
{
register char (*map)[10000] = myMap;
int sum = 0;
for (int r = 0; r < MAX; r++)
for (int c = 0; c < MAX; c++)
sum += map[r][c];
}
int main()
{
int TESTCASE = 10;
{
int TIME = 0;
/* Timer on */
clock_t start = clock();
/* 실행 코드 */
for (int tc = 1; tc <= TESTCASE; tc++)
{
test1();
}
/* Timer off */
TIME += ((int)clock() - start) / (CLOCKS_PER_SEC / 1000);
printf("\nNO REGISTER TIME : %d ms\n", TIME); /* ms 단위로 출력 */
}
{
int TIME = 0;
/* Timer on */
clock_t start = clock();
/* 실행 코드 */
for (int tc = 1; tc <= TESTCASE; tc++)
{
test2();
}
/* Timer off */
TIME += ((int)clock() - start) / (CLOCKS_PER_SEC / 1000);
printf(" REGISTER TIME : %d ms\n", TIME); /* ms 단위로 출력 */
}
return 0;
}
register가 속도 향상에 도움이 되지만, 알고리즘이 틀린 경우에 해결책이 되는 것은 아니다.
따라서, register는 코드 구현이 완료된 후에 추가하도록 하자.
'알고리즘 > [PRO] 삼성 SW 역량 테스트 B형' 카테고리의 다른 글
#define printf 재정의를 이용한 로그 출력 디버깅 팁 (0) | 2023.07.29 |
---|---|
BOJ 10999 : 구간 합 구하기 2 with 나중에 업데이트하기 (Top-Down Segment Tree with Lazy Propagation) (0) | 2023.01.16 |
BOJ 2042 : 구간 합 구하기 with 바텀 업 세그먼트 트리 (Bottom-Up Segment Tree) (0) | 2023.01.15 |
BOJ 2042 : 구간 합 구하기 with 탑 다운 세그먼트 트리 (Top-Down Segment Tree) (0) | 2023.01.15 |
BOJ 2042 : 구간 합 구하기 with 제곱근 분할법 (Sqrt Decomposition) (0) | 2023.01.15 |
댓글