Skip to content
Snippets Groups Projects
Commit 74a1aebb authored by 이소현's avatar 이소현
Browse files

Update README.md

parent 1f36d1fd
No related branches found
No related tags found
No related merge requests found
......@@ -527,3 +527,130 @@ int main()
>>> * 같은 코드여도 함수의 call을 줄이거나 늘리면 시간 계산이 또 달라진다.
>>> * 또한 오버플로우를 방지하기 위해 long long으로 a,b를 받아 곱하고 두 수의 곱을 int로 변환하여 받은 다음 gprof를 하여 시간계산 한 것을 확인하면 시간이 더 걸린 것을 볼 수 있다.
>>> * 위와 같은 것들은 오차가 넓기 때문에 5번 이상 돌려서 통계를 내어 사용하는 것이 좋다.
## lesson 11
1. call by address 와 call by value
>* &a 와 같은 것을 Call by address라 한다. (= call by reference)
>* c언어에서 기본은 automatic 으로 선언된다.
>* call by address는 주소값(*a)으로 가져오며 main에서 가져온 것과 같은 주소를 가진다. (즉, 연동되어 있다.) 따라서 이때 함수실행시 바뀐 값들은 main에서도 바뀌게 된다.
>* call by value는 변수값(a)으로 가져오며 main에서 가져온 것과 다른 주소를 사용하고 있게 된다.
>> 즉, 아예 다른 공간에서 동작하다가 함수 종료시 공간이 사라지게 되어 함수 실행시 변했던 값이 main에서도 바뀌지는 않는다.
* 함수 호출시 생기는 공간은 딱 맞춰 생성하는 것이 아니라 넉넉히 생성을 시킨다.
2. gprof 관련
>* $gprof를 쓰지 않으면 기본으로 a.out과 gmon을 비교해서 보여준다.
>* $gprof -A : 소스코드 함수에 Annitation을 달아준다.
>* $gprof -b : 간단하게 보게해주는 명령어이다.
3. optimization 관련
>* 사용하는 cpu에 따라서 optimization을 하여 어떤 type(int, long long, short, ...)으로 코드를 짜야 성능이 제일 좋은지 골라야 한다.
>* optimization은 꼭 필요할 때만 하는 것이 좋다.
4. 프로젝트(고정소수점) 관련
>* 맨앞의 비트는 signed 와 unsigned를 구분 하는 비트로 signed=1 이고, unsigned=2 이다.
> 1. (RGB로 보는 예) 4byte(unsigned int) 인 색을 나타내는 비트들에 대하여
>> * red(8bit) green(8bit) blue(8bit) a(8bit) 가 있다고 하자.
>> * 각각은 총 256개의 색을 (0~255) 나타낼 수 있으므로 총 256^3 개의 색상을 나타낼 수 있다.
>> * 0 = 0.0 , 255= = 1.0 으로 나타내므로 중간의 x번째는 x/255 로 표현한다.
> * 아래는 RGB 색상을 비트로 나타내는 코드이다.
```C
#include <stdio.h>
typedef unsigned int t_rgba;
#define fromRGBA(r,g,b,a) ((((r)&0xff)<<24)|(((g)&0xff)<<16)|(((b)&0xff)<<8)|((a)&0xff));
#define F_NUM_1_255 (1.0f/255.0f)
t_rgba mul_float(t_rgba c1, t_rgba c2)
{
float r1,g1,b1,a1;
float r2,g2,b2,a2;
int ir,ig,ib,ia;
r1 = (float) ((c1 >> 24) ) * F_NUM_1_255;
g1 = (float) ((c1 >> 16) & 0xff) * F_NUM_1_255;
b1 = (float) ((c1 >> 8) & 0xff) * F_NUM_1_255;
a1 = (float) ((c1 ) & 0xff) * F_NUM_1_255;
r2 = (float) ((c2 >> 24) ) * F_NUM_1_255;
g2 = (float) ((c2 >> 16) & 0xff) * F_NUM_1_255;
b2 = (float) ((c2 >> 8) & 0xff) * F_NUM_1_255;
a2 = (float) ((c2 ) & 0xff) * F_NUM_1_255;
ir = (int) ((r1 * r2) * 255.0f);
ig = (int) ((g1 * g2) * 255.0f);
ib = (int) ((b1 * b2) * 255.0f);
ia = (int) ((a1 * a2) * 255.0f);
return fromRGBA(ir,ig,ib,ia);
}
t_rgba mul_int(t_rgba c1, t_rgba c2)
{
unsigned int r1,g1,b1,a1;
unsigned int r2,g2,b2,a2;
int r,g,b,a;
r1 = c1 >> 24 ; r2 = c2 >> 24;
g1 = (c1 >> 16) & 0xff ; g2 = (c2 >> 16) & 0xff;
b1 = (c1 >> 8) & 0xff ; b2 = (c2 >> 8) & 0xff;
a1 = c1 & 0xff ; a2 = c2 & 0xff;
r = (r1*r2) >> 8;
g = (g1*g2) >> 8;
b = (b1*b2) >> 8;
a = (a1*a2) >> 8;
return fromRGBA(r,g,b,a);
}
//unsigned int fromRGBA(int r, int g, int b, int a)
//{
// return r*256*256*256 + g*256*256 + b*256 + a;
//return ((r<<24) + (g<<16) + (b<<8) + a);
// return (((r&0xff)<<24) | ((g&0xff)<<16) | ((b&0xff)<<8) | (a&0xff));
//}
int main()
{
int red, green, blue, alpha;
t_rgba rgba_1, rgba_2;
// input value must be in 0~255 : 0.0 ~ 1.0 으로 해석
// rgba_1 [rrrrrrrr][gggggggg][bbbbbbbb][aaaaaaaa]
printf("Input 4 values with 0~255 ");
scanf("%d %d %d %d", &red, &green, &blue, &alpha);
rgba_1 = fromRGBA(red, green, blue, alpha);
printf("%d %d %d %d : %u 0x%8x\n", red,green,blue,alpha,rgba_1,rgba_1);
rgba_2 = mul_float(rgba_1, rgba_1);
printf("%d %d %d %d : %u 0x%8x\n", red,green,blue,alpha,rgba_2,rgba_2);
}
```
* 위의 코드에서 rgba 에 대한 비트를 16진수로 [rrrrrrrr][gggggggg][bbbbbbbb][aaaaaaaa]형태로 짰다.
* 또한 처음에는 fromRGBA함수를 짰지만 성능상 define을 이용할 수 있다면 이용하는 것이 더 좋으므로
* #define fromRGBA(r,g,b,a) ((((r)&0xff)<<24)|(((g)&0xff)<<16)|(((b)&0xff)<<8)|((a)&0xff)); 로 정의 하였다.
>* 위에서 | 대신 +를 사용하여도 되지만 + 기호는 shift보다 우선순위가 높으므로 괄호를 잘 사용하여야만 한다!!!
>* 또한 r, g, b, a모두에 괄호를 사용하여 (r),(g),(b),(a)로 나타내었는데 이렇게 메크로엔 괄호를 하는 이유는 #define사용시에는 문자그대로 전달되기 때문에 r+2와 같은 값을 받아 들일때에 r+2&0xff 가 되어 계산이 꼬이는 경우가 생기기 쉽기 때문이다.
* 또한 조건문은 성능을 나빠지게 하므로 위의 코드에서 0~255사이 범위를 넘어가는 input을 받았을 때 처리해 주는 과정을 if문을 사용하지 않고 &0xff를 하여 처리해 주었다.
>> * 위에서의 "&" (and operation)은 각 자리수를 & 연산 한 것과 같다. (즉 0&0=0 1&0=0 0&1=0 1&1=1)
>> * 따라서 r,g,b,a에 각각 &0xff를 하면 r,g,b,a의 input 값과 0xff를 비교하여 둘 다 1인것만 1로 반환하므로 범위를 넘어가는 input은 모두 0으로 반환하여 잘 처리 할 수 있다.
* 위에서 fromRGBA를 정의한 것을 다시 살펴보면
> * 범위 처리를 위하여 각각의 r,g,b,a에 0xff 를 and operation 해주어 0~255범위가 넘어가는 것을 방지하고
> * 각각의 비트 위치에 따라 24번째 자리 부터 시작하는 red는 24번 왼쪽 shift 를 하였고(***왼쪽 shift 한번은 곱하기 2와 같다.)
> * green은 16번째 자리부터 시작하므로 16번 왼쪽 shift를 하였고
> * blue는 8번째 자리부터 시작하므로 8번 왼쪽 shift를 하여 자리수를 맞추어 주었다.
> * 마지막으로 a는 0~7번째 자리를 차지하는 비트이므로 0xff와 and operation만을 해주었다.
(cf)
* 16진수로 1자리는 2진수로 4자리 이다.
>> 16진수로 2자리는 2진수로 8자리
* 왼쪽 shift n이 곱하기 2^n 과 같듯이 오른쪽 shift는 나누기 2^n 의 몫과 같다.
* 보통은 역수를 구해야 하는 나누기가 곱하기보다 4배 정도 느리므로 나누기를 먼저 #define을 통해 곱하기로 처리하는게 성능에 더 좋다.
mul_float 코드
* 위의 mul_float는 두 개의 rgb를 나타내는 bit의 곱을 연산하는 코드이다.
* 먼저 두 rgb값의 각각의 r,g,b,a는 오른쪽 shift를 통해서 r, g, b, a로 각각을 나누어 준다.
* 그 다음 255로 나누어 (255번째 bit 가 1이므로) 각각의 r,g,b,a 로 쪼갠것에 대해 r1*r2, g1*g2, b1*b2, a1*a2 를 해준다.
* 그리고는 다시 255를 곱해주고 int로 변환하여 두 rgb의 곱한 rgb값을 return 하는 형태이다.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment