본문 바로가기
알고리즘/[PRO] 삼성 SW 역량 테스트 B형

함수의 매개변수와 배열의 register 속도 비교

by 피로물든딸기 2023. 8. 15.
반응형

삼성 B형 전체 링크

 

참고

변수 register 테스트

 

- B형에 필요한 최적화 코드 (1) (register 변수)

- B형에 필요한 최적화 코드 (2)

- 함수의 매개변수와 배열의 register 속도 비교

- 삼성 B형 디버깅 Tip

- 비주얼 스튜디오 output.txt 설정하기

- 삼성 SW 역량 시험 환경에서의 인라인 함수

- Visual Studio LNK1168: 쓰기용으로 열 수 없습니다 해결방법

 

변수 외에도 함수의 매개변수나 배열에 register 키워드를 추가하면 속도 향상 효과를 볼 수 있다.

특히, 자주 사용하는 배열일수록 효과적이다.


매개변수 register

 

같은 동작을 하는 test1test2 함수가 있다.

test2parameterregister를 추가하였다.

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코드 구현이 완료된 후에 추가하도록 하자.

반응형

댓글