코드 가속에 대한 사고

1421 단어
이라는 책에서 이러한 지식이 나의 주의를 끌었다.
예를 들어 다음 코드는 다음과 같습니다.
코드 1:
	const int length = 100000;
	float data[length];
	memset(data,1,sizeof(float)*length);

	for ( int i = 0; i < length; ++i )
	{
		data[i] = 3.0;
	}

우리가 이 순환을 사용할 때 다음과 같은 형식으로 바꾸면
코드 2:
for ( int i = 0; i < length - 3; i += 3 )
	{
		data[i] = 3.0;
		data[i+1] = 3.0;
		data[i+2] = 3.0;

	}

즉 순환 중에 매번 세 개의 데이터를 처리하면 시간이 크게 줄어든다는 것이다. 책에서는'unrolling'기술이라고 부른다.
나는 매번 세 개의 변수를 사용하고 세 개의 데이터를 동시에 처리하면 신마 효과가 있을 것이라고 생각한다.다음 코드 3은 제 생각입니다.
코드 3:
int maxI = length/3;
	int maxJ = 2*length/3;
	for ( int i=0,j=length/3+1,k=2*length/3 +1; i<maxI && j<maxJ && k<length; ++i,++j,++k)
	{
		data[i] = 3.0;
		data[j] = 3.0;
		data[k] = 3.0;
	}

다음은 debug과release 버전의 시간 복잡도 대비입니다.
 
debug
release
코드 1
0.242ms
0.0ms
코드 2
0.101ms
0.055ms
코드 3
0.121ms
0.076ms
여러분, 일단 코드1과 코드2를 비교해보도록 하겠습니다.
debug 모드에서 이 책에서 언급한 기술은 확실히 코드를 가속화시킬 수 있지만release 버전에서는 오히려 우리가 자주 사용하는 순환의 효율이 높지 않다. 아마도 코드 1을 겨냥한 것 같다. 소 B의 컴파일러는 이를 깊이 있게 최적화할 수 있을 것이다.(memset과 비슷한 것을 사용했을 수도 있다). 그러나 코드 2에 대해서는이런 그다지 정상적이지 않은 방법은 오히려 컴파일러의 최적화 효율을 떨어뜨렸다.
코드 3은 코드 2의 원리와 마찬가지로 실현할 때의 방식이 다르다. 몇 개의 변수가 많아졌기 때문에 순환할 때마다 부담이 약간 크고 코드 2의 시간 복잡도보다 조금 높아도 이해할 수 있다.

좋은 웹페이지 즐겨찾기