제너레이터는 딥러닝에서 학습용 데이터의 Batch를 만들 때 많이 사용된다.  

제너레이터를 이해하기 위해서는 다음과 같은 함수를 먼저 소개한다.  

시작할 때 print를 이용하여 메시지를 출력하고, 0부터 4까지 각 값의 제곱을 val이라는 리스트에 추가하여 반환해주는 함수이다.  

def method():
	print("Start method()")
    val = []
    for x in range(0, 5):
    	val.append( x**2 )
   	return val

 

그러나 Return 키워드를 사용한 코드에는 성능 문제가 있다.  

만약에 range(0, 10000) 같이 범위가 매우 커지면, 메모리 공간도 부족하고 성능도 저하된다.  

 

out = method()
for i in range(0, 5):
	print(out[i])

 

out = method() 가 실행되는 순간 for문을 돌고 나온 후 리스트가 반환된다.  

다음과 같이 출력값이 나온다.  

# Start method()
# 0
# 1
# 4
# 9
# 16

 

제너레이터는 이와 같은 메모리 문제와 성능 저하 문제를 해결해줄 수 있다.  

Yield 키워드를 사용하여 제너레이터를 이용할 수 있다.  

def generator():
	print("Start generator()")
    for x in range(0, 5):
    	yield x**2

 

방금 전 살펴보았던 method()와는 다르게 다음과 같이 generator()를 실행해도 메시지가 출력되지는 않는다.  

gen = generator()

 

계산 부분이 아직 실행되지 않은 채로 제너레이터가 선언만 되어 있는 상태이다.  

다음과 같이 next()를 사용해야 실제 계산이 실행된다. 

for i in range(0, 5):
	print(next(gen))

 

next를 호출할 때마다 yield까지만 실행이 된다.  

그러므로 메모리 공간도 아낄 수 있고 성능 저하도 막을 수 있다.  

 

 

'프로그래밍 > Python' 카테고리의 다른 글

Python - Closure 함수  (0) 2023.12.15
Python - 클래스 속성과 메서드 사용  (2) 2023.11.25
Python - 인스턴스 변수 vs 정적변수  (0) 2023.11.25
Python - 클래스 생성자  (2) 2023.11.25
Python - 클래스  (1) 2023.11.25

7-1 인공 신경망.ipynb
0.07MB
7-2 심층 신경망.ipynb
0.03MB
7-3 신경망 모델 훈련.ipynb
0.24MB

'프로그래밍 > 머신러닝' 카테고리의 다른 글

LightGBM  (1) 2024.09.04
다변량 이상치 탐지 방법  (0) 2024.08.25
정규 표현식 (Regular Expression)  (0) 2024.08.23
로지스틱 회귀분석  (0) 2024.08.13
혼자 공부하는 머신러닝 + 딥러닝(머신러닝)  (0) 2024.07.19

 

 이 책은 굉장히 오래된 책이다. 

 그럼에도 불구하고 아직도 사람들이 찾는 이유가 뭘까? 이 책을 읽으면서 알게 되었는데, 일단 주식 투자에 대해 어떤 가치관과 사고관을 가져야하는지 알려주는 책이다. 요즘같이 정보의 홍수시대 속에서는 소위 말해 경제 전문가, 투자 전문가의 말에 사람들의 의견이 휩쓸리기 쉽다. 이럴 때일수록 정보가 아닌 그 속에 있는 알맹이를 보는 것이 더 중요하다.

 이 책의 1부에서 나한테 가장 와닿았던 것은 '주식의 단기 등락을 무시하라.'는 것이었다. 나는 아침에 한 번, 점심에 한 번, 3시에 한 번 현재 주가 차트를 보는 습관이 있다. 오르는 날의 하루는 굉장히 기분 좋게 시작하고, 내리는 날의 하루는 무언가 찝찝한 느낌으로 하루를 시작한다. 바로 이러한 느낌이 들지 않도록 주식의 단기 등락을 무시하라는 것인데, 이 책에서 말하기를 가치가 있는 주식은 언젠가 오르게 된다는 것이다. 그런데 이걸 누가 모르겠나 다 아는 사실이지. 그런데 모두가 다 알면서도 하지 않는 것이 현실이다. 그렇기 때문에 나는 이 말을 앞으로 주식에서 관철해 나갈 것이다. 

 그리고 또 하나 인상깊었던 구절은 대기업은 움직임이 둔하다는 것이다. 이게 진짜 맞는 말인게 내가 삼성전자를 조금 가지고 있는데 누구나 알다시피 삼성전자는 전세계가 알아주는 대기업이다. 그런데 이렇게 큰 대기업의 주식을 아무리 좋은 가격에 산다고해도 2년 안에 대박을 터트리는 것은 거의 불가능하다. 왜냐하면 성장이 어느 정도 안정화된 상태이기에 빠르게 성장할 수 있는 기업이 아니기 때문이다. 이 점은 동의한다. 그래서 이 책에서는 '다른 조건이 같다면, 소형주에 투자해야 유리하다.'라고 한다. 하지만, 우리나라의 경우 소형주에 잘못 투자하면 상장 폐지가 되어 돈을 한순간에 다 잃을 수 있기에 이 구절은 조금 비판적으로 읽어야한다고 생각한다. 

 

 책 자체가 약간 전문적인 느낌으로 투자를 할 때 이렇게 하세요, 저렇게 하세요 느낌보다는 어떤 마음가짐으로 시작하는 것이 좋은지에 대해 알려주고 있다. 그런데 나는 이 책이 조금 아쉬운 점이 이 책에서 전달하는 지식이 현재의 주식시장에 비해 비교적 변동성이 낮은 과거의 주식시장을 기준으로 말하기에 이것을 현재의 주식 시장에 적용되는지는 의문이다. 그렇지만 주식을 입문하기 전에 가볍게 읽기에는 좋은 책이라고 생각해서 주식을 이제 시작하려고 하는 사람들한테 강력하게 추천한다. 

 

1-3 마켓과 머신러닝.ipynb
0.05MB
2-1 훈련 세트와 테스트 세트 240701.ipynb
0.07MB
2-2 데이터 전처리 240701.ipynb
0.29MB
3-1 k-최근접 이웃 회귀.ipynb
0.03MB
3-2 선형 회귀.ipynb
0.11MB
3-3 특성 공학과 규제.ipynb
0.08MB
4-1 로지스틱 회귀.ipynb
0.06MB
4-2 확률적 경사 하강법.ipynb
0.11MB
5-1 결정 트리.ipynb
0.72MB
5-2 교차검증과 그리드서치.ipynb
0.77MB
5-3 트리의 앙상블.ipynb
1.43MB
6-1 군집 알고리즘.ipynb
1.06MB
6-2 k-평균.ipynb
1.75MB
6-3 주성분 분석.ipynb
3.78MB

 

 

위의 내용은 7월 2주동안 공부한 내용인데

원래 한 달안에 끝내는 마음으로 이 책을 시작했는데, 너무 내용을 쉽게 풀어서 써줘서 생각보다 빨리 끝날 것 같다.  

이 책이 진짜 쉽게 설명한 만큼 내용이 깊지는 않은데

추후에 깊게 공부하기 위해 전반적인 내용을 훑어본다는 느낌으로 공부하면 좋을 것 같다. 

 

딥러닝 파트도 끝나면 정리해서 올려야겠다. 

(내용은 모두 혼자 공부하는 머신러닝 + 딥러닝을 기반으로 작성되었다.)

'프로그래밍 > 머신러닝' 카테고리의 다른 글

LightGBM  (1) 2024.09.04
다변량 이상치 탐지 방법  (0) 2024.08.25
정규 표현식 (Regular Expression)  (0) 2024.08.23
로지스틱 회귀분석  (0) 2024.08.13
혼자 공부하는 머신러닝 + 딥러닝(딥러닝)  (0) 2024.08.08

 

 

메모리 반도체

메모리 반도체: 데이터를 기록하고(쓰고) 필요할 때 꺼내는(읽는)  즉, 가장 기본적인 역할을 담당하는 반도체

 

메모리 반도체 종류 

램(Random-Access Memory) D램: 구조가 단순, 생산성 좋음, 성능 좋음
S램: 속도가 빠름.

용량이 작음. 
전원이 꺼지면 데이터가 휘발됨.
롬(Read-only memory) 전원이 꺼져도 데이터가 휘발되지 않음.
용령이 큼.
수정은 불가능.

>> 그런데 수정할 수 있게 개발된 것이 낸드플래시 

 

HBM : D램들을 탑처럼 쌓아올린 메모리 반도체 

  • 면적당 기억능력 상승, 전력 소모 감소, 데이터 전송 속도 증가 

 

보통 반도체를 구성하는 소자들은 구리 배선, 즉, 와이어를 이용해 연결하는데 직관적이고 간편한 방법이지만 반도체 구조가 복잡할수록 와이어가 너무 많아져 서로 간섭하거나 물리적으로 연결할 공간이 부족해진다. 

하여 와이어를 없애고 소자들에 구멍을 뚫은 다음 구리를 충전, 즉 흘려넣음으로써 연결하는 방식이 개발됨. 

이것이 TSV(Through Silicon Via).

 

TSV는 소자와의 접촉면이 와이어보다 넓은만큼 전력공급이 효율적이고 신호전달이 빠르다.

(전력소모 감소, 데이터 전송 속도 증가)

또한, 소자를 안정적으로 쌇을  수 있어 집적도도 상승한다. 

 

 

시스템 반도체

시스템 반도체: 데이터를 계산하고 이해하는 반도체

ex) CPU(컴퓨터), AP(스마트폰, 스마트워치)

 

CPU연산

  • 직렬연산
  • 따라서 연산이 多. 아무리 똑똑한 CPU라도 속도 감소할 수 밖에 없음. 

GPU연산

  • 병렬연산
  • 동시에 수천, 수만 번의 연산을 수행하는 만큼 속도면에서 용이 

 

PIM(Processing In Memory)

  • 메모리 반도체 + 시스템 반도체 (연산하는 기억장치)
  • 메모리 반도체가 일부 연산을 수행한 다음 데이터를 넘기므로, CPU로서는 그만큼 빨리 나머지 연산을 마칠 수 있다. 
  • 그만큼 전력 소모도 감소하고, 발열도 줄어든다.
  • 빅데이터 처리와 딥러닝에 최적화되어있다. 

 

 

 

펩리스(fabrication less) : 반도체 설계 분야 

 

파운드리 (foundry) : 설계도, 반도체 생산 분야 

 

반도체를 단순히 생산한다고해서 모두 파운드리인 것은 아니다.

가령 자체적으로 설계한 반도체를 스스로 생산하는 것은 파운드리가 아니다. 

파운드리는 외부 펩리스에 주문을 받아 위탁 생산을 하는 것을 말한다. 

 

IDM(Integrated Deduce Manufacturer): 펩리스이자 파운드리인 기업 

 

반도체 제조장비 회사 >> ASML, ASM(네덜란드) / 어플라이드 머티리얼스(미국) / 도쿄 일렉트론(일본)

 

 

시장 점유율 (2023년 기준)

D램 시장 점유율: 삼전 > 하이닉스 > 마이크론 

낸드플래시 시장 점유율: 삼전> 하이닉스 > 키오시아 >= WDC > 마이크론

시스템 반도체 나라별 시장 점유율 : 미국 > 유럽 > 타이완 > 일본 > 중국 > 한국

파운드리 시장 점유율 : TSMC > 삼전 > UMC > 글로벌 파운드리 > SMIC

팹리스 시장 점유율 : 미국 > 타이완 > 중국 > 일본 > 한국 

 

 

반도체 생산과정

- 웨이퍼 제조

- 산화

- 포토: 반도체 소자의 회로를 웨이퍼에 새기는 공정 

  • 웨이퍼 위에 빛에 반응하는 감광색을 얇게 바르고
  • 회로가 인쇄된 투명한 유리인 마스크를 올린다. 
  • 빛을 쏘면 감광액 반응이 일어남. 
  • 웨이퍼에 양각(회로가 인쇄된 마스크)이나 음각(회로의 영역이 인쇄된 마스크)으로 회로가 새겨짐. 
  • 이걸 하는 것이 노광장비

노광장비(EUV)를 제일 잘하는 회사가 호주의 ASML이다. 

포토공정에서 가장 중요한 것이 빛의 회절 정도를 줄이는 것이 관건인데 파장이 짧은 빛을 사용하면 된다. 

(끼고 돌아 구부러지는 각도가 작아지기 때문)

(파장의 길이는 빛의 에너지와 반비례한다.)

 

- 식각

- 증착

- 금속 

- 배선 

- 패키징: 반도체 포장 공정 

  • 물리적, 화학적 충격에서 완벽하게 보호 및 발열 최소화.
  • 전력공급과 신호전달이 더욱 효과적으로 이루어지도록 보호한다. 

 

검은색 사각형, EMC(Epoxy Mold Compound) - 포장지 

EMC안에 반도체의 진짜 알맹이인 각종 소자가 복잡하게 조립되어 있음.

 

금속 와이어, 리드 프레임(Lead Frame)

반도체를 기판과 단단히 연결하는 동시에 전력을 공급한다. 

 

FOPLP, FOWLP

삼성전자 >> FOPLP(Fan - Out - Panel - Level - Packaging, 사각형 패널) 

TSMC >> FOWLP(Fan - Out - Wafer - Level - Packaging, 둥근 웨이퍼)

 

FOWLP

 

'다이(die)' - 패키징 공정을 거치지 않은 반도체.

이것이 아직 웨이퍼 위에 있는 채로 '몰딩'(다이를 에폭시로 감싸주는 과정).

이 과정에서 몰딩 소재를 웨이퍼 크기만큼 펴 바르게 되는데, 그러면서 다이를 몰딩 소재 위로 옮기고 웨이퍼를 제거 이후 나머지 작업 (재배선과 솔더볼 설치, 반도체별 절단)을 계속해 반도체 완성. 

 

웨이퍼를 제거하는 만큼 반도체의 두께와 부피를 크게 줄일 수 있고 발열도 최소화가 가능하다.

반도체가(FOPLP 채널 내부에 포함된 패널을 거치지 않고) 전자장치의 기판과 곧바로 연결되므로, 전력공급과 신호 전달 효율 상승

 

대신 생산량에 손해를 본다.

둥그런 웨이퍼 위에 네모난 반도체를 잔뜩 올려놓으면 테두리를 따라 '데드 존', 즉 버려지는 공간이 생길 수 밖에 없다. 

 

 

FOPLP

 

웨이퍼에서 다이를 떼어낸 다음, 그 크기에 맞춰 뚫어놓은 페널의 네모난 구멍 속에 넣고 몰딩과 나머지 작업을 진행한다. 

패널을 이용하므로 반도체 안에 또 하나의 작은 기판을 설치하는 셈이다. 

데드존이 거의 없다. 

생산량이 좋다. 

 

대신 열을 받으면 휘어진다. 

CPU나 AP처럼 연산과정에서 열을 많이 내는 반도체에는 FOPLP 적용을 하지 않는다. 

 

 

 

 

소재

솔더: 반도체 소자를 접합할 때 사용되는 합금 (다무라, 센주금속공업)

 

반도체는 실리콘으로 만든 원판인 웨이퍼에 설계도를 새기고 깎은 다음 소자를 설치해 만든다. 

(포토레지스트 - 설계도를 새길 때 / 불화수소 - 깎을 때 / 폴라이미트 - 소자의 보호막으로서 소자를 설치할 때)

 

 

유기소재는 무기소재보다 전기이동도가 매우 떨어진다. 

 

2차원소재 (ex - 그래핀) 

  • 원자 하나 정도의 아주 얇은 두께
  • 전기금속 칼코겐 화합물 (TMD), 비정질 질화붕소(aBN) : 유전율이 낮아서 전류가 잘 흐름. 

 

 

 

반도체는 트랜지스터로 구성됨. 

반도체는 전자의 흐름을 제어하는 트랜지스터로 구성됨. (트랜지스터는 모스펫으로 만들어짐.)

트랜지스터: 게이트(gate), 채널(channel), 소스(Source), 드레인(drain)

 

소스에 전압을 가해주면 전자가 채널이라는 통로로 흐른다. 흘러서 도착하는 곳이 드레인. 

여기서 전자의 흐름을 제어한다는 점에서 게이트를 '문'에 전자가 다니는 길이라는 점에서 채널을 '통로'에 비유 

 

여기서 전자가 이동하는 거리, 즉 게이트의 폭이자 채널의 길이가 몇 나노인지를 결정한다. 

 

나노 미세화에 열을 올리는 이유

> 거리가 짧아지면 트랜지스터 크기는 작아지고 트랜지스터 크기가 작아지니 하나의 반도체 안에 더 많이 집적할 수 있고 그러면 전자가 더 빨리 이동할 수 있고 데이터 처리 속도는 향상되며 전력소모는 줄어든다. 그렇게 해서 성능이 올라가기 때문에 대기업들이 나노 미세화에 열을 올리는 중이다.

 

터널 효과

반도체는 기본적으로 전자의 흐름을 제어하는 장치이다.

그런데 반도체가 너무 작아지면 전자가 통로, 즉 채널을 뚫고 엉뚱한 곳으로 이동할 수 있다. 

거시세계가 아닌 미시세계의 물리법칙인 양자역학에 영향을 받기 때문이다. 

이를 터널효과(터널링)이라고 한다. 

이것을 방지하거나 활용하면 반도체는 좀 더 효율적으로 전자의 흐름을 제어할 수 있다. 

그렇게 해서 제시된 해결방안이 '채널의 길이는 짧게 유지하되, 게이트와 닿는 면의 개수를 늘려보자'

 

핀펫(닿는 면이 세 개) - 인텔(2010년대 초반)

GAA(닿는 면이 네 개) - 삼성전자

 

7나노 반도체까지는 핀펫 OK, 하지만 그 이하로는 다른 구조가 필요하다. (그래서 나온 것이 삼성전자의 GAA)

 

2022년 6월 삼성전자는 GAA로 3나노 반도체 양산을 세계최초로 성공했다. 

 

 

 

2차전지 

반도체와 2차전지는 완전히 구분되는 분야가 아니다.

전기자동차에 쓰이는 고성능 2차전지에는 제어장치의 일부로 반드시 반도체가 들어간다.

 

2차전지는 리튬이온이 양극재와 음극재 사이를 오가며 전기를 충전하고 방출한다. 

이때 양극재와 음극재의 사이에서 리튬이온의 통로가 되는 것이 전해질, 2차전지의 전해질은 액체다. 

액체는 그런데 물리적으로 불안정하다.

반면에 전고체 배터리는 말 그대로 전해질이 고체이다. 따라서 안정적이고 기존의 2차전지보다 에너지 효율도 좋다. 

 

소재 비율이 어떻게 되느냐에 따라 배터리의 효율이 결정된다. 

 

배터리 개발이 비싼 이유는 리튬이 채굴과 가공이 쉽지 않기 때문이다. 

 

배터리 생산량이 증가하면 원가가 절감되고, 배터리 성능이 또 증가하면 가격이 줄어든다. 

그러면 전기자동차가 싸진다. (배터리가 차지하는 비율이 40% 이상이기 때문이다.)

 

LFP배터리(리튬, 철, 인산)이 3000사이클까지 가능한데 이것이 대부분 중국제이다. (31% 차지)

 

 

딥러닝

딥러닝은 인간의 뉴런과 시냅스의 작동 방식을 모방한 '인공신경망' 방식의 알고리즘으로 빅데이터를 분석한다.

 

입력층, 은닉층, 출력층으로 구성된다. 

 

핵심은 은닉층의 층수와 각 층에서 연산을 수행하는 '노드'의 수이다.

 

즉, 은닉층의 층수가 많고 각 층의 노드가 많을수록 입력층에서 투입된 데이터가 출력층을 향해가는 과정에서 거치는 연산과정이 기하급수적으로 증가한다. (각 노드는 이전 층의 모든 노드의 결괏값을 연산한다.)

 

NPU(Neural Processing Unit) : 딥러닝, 또는 머신러닝에 특화된 인공지능 반도체를 ANN방식의 알고리즘을 지원한다. 

 

 

구글 딥마인드

- 알파폴드 

  > 단백질의 2차원구조(아미노산들의 염기서열)로 먼저 그려본 다음, 이것들을 보아 최종적으로 3차원구조로 형성.

 

- 로제타 폴드

  > 2차원구조와 3차원구조를 동시에 만들어 비교하면서 완성도를 끌어올림. 

 

 

구글 인공지능 PaLM(Pathway, Language Model)

언어모델: 인간의 언어를 이해할 수 있는 인공지능, 텍스트로 구성된 대량의 데이터를 학습해 인간과 소통한다. 

 

PaLM은 정말 필요한 데이터 위주로만 학습한다.

딥러닝 성능을 크게 높여 빅데이터가 아닌 스몰데이터 만으로도 충분한 성능을 발휘할 수 있도록 설계됨. 

 

 

 

클라우드

클라우드는 따로 서버가 필요하지 않다. 광대한 네트워크 자체를 가상화된 서버로 사용한다. 물론 그 네트워크를 유지하기 위해 물리적인 서버가 필요하긴 하지만, 그 개수를 크게 줄이는 것이 가능하다. 

 

클라우드에 인공지능 반도체가 필요한 이유

  • 클라우드에는 막대한 데이터가 여기저기에 분산되어 있음.
  • 이 중 사용자가 원하는 것을 재빨리 찾아줘야 함.
  • 작업내용을 실시간으로 백업, 훗날을 위해 잘 보이는 곳에 쌓아두기
  • 이는 병렬 연산에 특화된 GPU가 잘할 수 있는 일들이다. 
  • 그런데 사용자와 데이터가 많아지면서 더욱 고성능의 인공지능 반도체가 필요해졌다.
  • 게다가 인공지능 반도체는 효율이 매우 좋아 전력도 적게 소모한다. 
  • 클라우드 서비스를 제공하는 기업들이 반도체를 자체 개발하는 이유가 바로 이것이다. 

 

 

 

컴퓨터 비전: 인공지능이 얼마나 정확하게 시각정보를 인식하는지

BCI(Brain Computer Interface): 인공지능이 인간의 뇌와 곧바로 연결되어 상호작용

 

 

 

로봇 

로봇의 핵심부품

: 구동용 부품(서보모터, 감속기 등), 제어용 부품(컨트롤러 등), 구조용 부품(엔드 이펙터 등), 센서 

 

로봇산업은 반도체 산업만큼이나 보수적이다.

반도체 기업들이 불화수소 같은 소재의 공급처를 쉽게 바꾸지 않으려고 하는 것처럼, 로봇 기업들도 중요부품의 공급처를 잘 바꾸려 하지 않는다. 

 

 

 

전장 반도체 

전장 반도체: 자동차에 들어가는 각종 전자 장치에 쓰이는 반도체 

 

전장 반도체는 그 쓰임에 따라 여러 종류로 구분된다. 

 

 

아날로그 반도체: 아날로그 신호를 디지털 신호로 바꿔주는 반도체 

  • 빛, 소리, 압력, 온도 같은 것들을 전자장치가 이해할 수 있는 디지털 신호, 즉, 0과 1의 조합(기계어)으로 변환하는 것.
  • 가령 자율주행 자동차는 주행 중에 사방이 무엇이 있는지, 자신의 위치가 어디인지, 얼마나 빠르게 달리고 있는지 등을 실시간으로 파악해야한다. 
  • 이때 세상의 무수한 아날로그 신호를 순식간에 디지털 신호로 바꿔주는 기계어 전문가가 아날로그 반도체다. 
  • 스마트폰이나 디지털 카메라에 부착된 이미지 센서도 가장 대표적인 아날로그 반도체다. 

전체 전장 반도체 시장에서 아날로그 반도체 시장의 비중은 59퍼센트에 이른다. 

아날로그 반도체를 지배하는 자가 전장 반도체를 지배한다. 

우리나라의 대표적인 기업으로는 LX세미콘이 있다. 

 

LX세미콘 주력 상품 중 하나가 디스플레이용 아날로그 반도체. 

 

 

 

화합물 반도체: 특정한 성질을 얻기 위해 여러가지 물질을 화합해 만든 반도체 

  • 가령 실리콘으로만 만든 반도체는 열에 약하다. 150도만 넘어가도 기능을 상실한다. 이러면 전장 반도체로 쓰기 힘듦.
  • 반면에 실리콘에 탄소를 결합한 '실리콘카바이드(SiC)'나 질소와 갈륨을 결합한 '질화갈륨(GaN)'으로 반도체를 만들면 각각 2000도와 1000도 이상의 고열을 견뎌낸다. 
  • 자연스레 고전압도 견딜 수 있어 사용처가 무궁무진하다. 
  • 전기자동차에서 전압을 분배하는 역할을 맡는 전력 반도체(업계에서는 전력 반도체와 화합물 반도체를 동의어처럼 쓴다.)로의 쓰임이 대표적이다. 

 

 

뉴로모픽 반도체

인간의 뇌와 비슷한 구조의 반도체 

 

CPU는 연산단계마다 올바른 진단을 위해 끊임없이 램에서 데이터를 불러온다.

그렇게 하나하나 답을 찾아간다. 그러다가 중간에 잘못된 판단을 하면 최종결과가 틀리게 된다.

 

그러나 뉴로모픽 반도체는 동시다발적으로 저장과 연산, 실시간 피드백을 수행하여 전력소모가 감소한다. 

 

뉴런의 접점이 100조 개에 달하는데 엄청난 물량을 재현하려면 반도체 소자의 집적도를 극한의 수준까지 밀어붙여야 함.

>> 해결책: TSV

 

이종집적

말 그대로 다른 종류의 반도체를 하나로 합치는 것.

Sip(System in Package)

  • 여러 기능의 반도체를 하나로 묶는 것.
  • CPU, GPU, D램을 하나로 묶음.

SoC(System in Chip)

  • 하나의 반도체 안에 CPU, GPU, D램이 다 있음.
  • 공간활용과 전력에 이점이 있다. 

 

 

디지털 반도체 vs. 양자 반도체

디지털 반도체 양자반도체
슈퍼컴퓨터를 포함해 우리가 현재 일반적으로 사용하고 있는 디지털 컴퓨터의 반도체 미세한 입자의 흐름을 따름.
정보의 최소단위는 비트 큐비트
한번에 '1' 또는 '0'을 가진다. 
(거시세계의 논리) >> 이것이 곧 정보
'1'일 수도 있고 '0'일 수도 있음. 
입자의 중첩(양자얽힘)현상 이용
2비트는 네 번에 걸쳐서 정보를 나타냄. 2큐비트는 한번에 00, 01, 11, 01 을 동시에 정보로 나타냄. 
속도가 훨씬 빠름.

 

 

엔비디아

CUDA(Compute Unified Device Architecture)

- 그래픽 외에 일반적인 데이터의 연산을 수행한다. 

 

이것을 무료로 제공하였는데

그 이유는 하드웨어와 소프트웨어를 아우르는 엔비디아의 생태계를 구축하고자 하였기 때문이다. 

 

 

세레브레스 시스템스(Cerebras systems)

WSE(Wafer Scale Engine)

- 거대한 크기의 반도체

 

대부분의 반도체는 기판을 통해 반도체나 부품과 연결된다. 

바로 이 기판 그리고 기판과 반도체를 연결하는 접합부에서 전기신호 지연의 50%가 발생한다. 

즉, 기판만 없애도 성능을 50% 정도 끌어올릴 수 있다는 것이다. 

 

 

ACCEL

ACCEL (All - analog Chip Combining Electronics and Light) - 중국에서 개발됨.

- 아날로그 광전자 반도체 

 

일반적인 아날로그 반도체는 컨버터(변환기)를 통해 현실의 아날로그 신호를 컴퓨터가 다른 전기신호로 바꿔준다. 

ACCEL은 컨버터가 없다.

대신 아날로그 신호를 일단 받아들인 다음, 그 자체로 전류나 전압을 발생시키는 '포토다이오드'가 들어간다.

그래서 기존의 아날로그 반도체에 비해 뛰어난 성능을 가지고 있다. 

 

인공지능 개발에 쓰이는 엔비디아의 A100보다 연산속도는 3000배 빠르고, 전력소모는 400만 배 적다는 것을 증명하였다. 

발열도 거의 발생하지 않는다. 

 

ACCEL은 아날로그 신호를 디지털신호로 변환하는 대신 그 자체로 다루기 때문에 연산을 하지 않는다. 

특히 미세화가 불필요하다. 

 

그러나 상용화하기에는 빛 처리만 가능하다는 한계가 있다. 

 

 

미국의 반도체 전략

미국의 대중 반도체 규제(반도체법)

- 요약: 반도 기업이 중국에 투자하지 않으면 미국정부가 직접 보조금을 줄거다.

- 주요내용

  • 예상보다 수익을 많이 내면 보조금을 토해낼 것
  • 미국 정부가 반도체 시설에 접근할 수 있도록 할 것 
  • 중국에 투자하지 말 것
  • 미국에 시설을 짓고 미국인을 채용할 것
  • 가격을 낮춰 치킨 게임을 하지 말 것 

 

미국의 큰 그림 

  • 반도체 설계 : 미국
  • 반도체 소재 공급 : 일본
  • 반도체 양산(파운드리) : 한국 & 타이완

 

반도체 대란 

2021년 팬데믹 시기 반도체 대란 이유

  1. 팬데민 때문에 신차 구매가 감소할 것으로 예측한 자동차 기업들이 전장 반도체 발주량을 줄였다.
  2. 전장반도체 기술의 낙후.
  3. 천재지변(지진과 화재로 르네사스 일렉트로닉스 공장 파괴 / 텍사스 주 한파 인피니언, NXP 반도체 공장 가동 중단)

전장 반도체 시장이 매년 10퍼센트씩 꾸준히 성장할 것으로 보이자, 삼성전자와 SK하이닉스가 그에 맞춰 대응하고자 하는 중이다. 

 

현재 삼성전자는 이미 테슬라에 14나노 전장 반도체를 공급 중이다. 이후 4나노 전장 반도체 공급도 삼성전자가 따낼 가능성이 크다. 

 

삼성전자는 하드웨어에 집중하고 SK하이닉스는 소프트웨어에 집중하고 있다. 

 

 

K칩스법

보통 자산을 기준으로 10조원 이상은 대기업, 5000억원 이상, 1조원 미만은 중견기업, 5000억원 미만은 중소기업이다. 

대기업과 중견기업에 15퍼센트, 중소기업에 25퍼센트의 세제 혜택을 주는 조정안이 2023년 3월 국회를 통과했다. 

 

 

 

 

 

 

+

나노: 나노미터(1나노미터는 10억분의 1미터)

 ex) 인간의 머리카락은 8나노미터 정도

 

유전율: 전류가 외부 자기장에 영향받는 정도 

 

모뎀: 원활한 무선통신을 지원하는 반도체

무선통신: 잔파에 데이터를 실어 주고 받는 것 

모뎀은 데이터를 전파에 실을 수 있도록 변환하는 일, 전파에서 데이터를 분리하는 일을 모뎀이 담당한다. 

 

 

LED: 전기신호를 광신호로 바꿔주는 발광소자, 반도체의 일종 

 

청색 LED

  • 기존에 개발된 적색 및 녹색 LED와 함께 삼원색을 완성하는 마지막 퍼즐이었다.
  • 빛은 파장이 낮아지면 에너지가 증가한다. 삼원색 중 청색의 파장이 가장 짧다. 
  • 즉, LED가 청색을 띠려면 높은 에너지를 발산해야 하는데 이 정도의 전류 흐름 제어는 쉽지 않다. 
  • 그런데 2014년 일본에서 개발됨.
  • 에너지 효율을 높일 수 있다는 점에서 매우 각광받는 중이다.

 

전기신호지연의 50%가 접합부에서 발생한다. 

 

재배선: 몰딩 중에 흐트러진 배선을 바로잡거나 강화하는 과정.

솔더볼: 기판과 반도체를 연결해 전력을 공급하고 신호를 전달하는 부품. 

 

FI(Fan - In) : 솔더볼을 다이 크기를 넘지 않을 만큼만 설치하는 것.

FO(Fan - Out): 솔더볼을 다이 크기를 넘어갈 정도로 설치하는 것. - 구조 특성 상 전력공급과 신호전달에 유리.

 

 

V2X (Vehicle-to-Everything)

: 도로를 함께 주행 중인 다른 자동차들과 연결되어 정보를 주고 받는 것.

 

언어모델: 인간의 언어를 이해할 수 있는 인공지능, 텍스트로 구성된 대량의 데이터를 학습해 인간과 소통한다. 

 

배터리 수명 단위 사이클 (Cycle)

: 1사이클은방전된 배터리를 최대치까지 1회 충전하는 것을 말한다. 

: 만일 500 사이클이 넘어간 스마트폰이 있다면 그 스마트폰은 배터리용량이 80%미만일 것이다. 

'독서 > 과학' 카테고리의 다른 글

카이스트 미래전략 2024  (3) 2024.02.20
AI 이후의 세계  (1) 2024.01.19

 

시험도 끝났고 계절학기 수업도 안 맞는거 같아서 책이나 많이 읽자는 마음으로 교보문고에 갔다.

그곳에서 유달리 나의 이목을 끄는 책이 한 권 있었는데 그 책이 바로 '도둑맞은 집중력'이었다. 

 

처음 머리말을 읽었을 때는 '작가가 왜 이렇게 분노해있고 위기감에 휩싸인거 같지?' 라는 느낌을 받았다. 

그도 그럴 것이 집중력의 감소가 비만율의 증가로 이어졌고 아이들의 집중력은 점점 퇴화하고 있다는 글쓴이의 주장이 이어졌기 때문이다. 황당했다. 집중력의 감소와 비만율 간의 어떤 상관관계가 있길래 글쓴이가 이렇게 주장하는지 궁금했다. 

더군다나 나 자신도 현재 어떤 한 가지 일에 제대로 집중을 못하고 있는데 이 책을 통해서 얻어가는게 있을까? 라는 생각에 '도둑맞은 집중력'을 읽게 되었다.

 

1, 2, 3, 4, 5장은 자신이 프로빈스 타운에서 집중력을 높이기 위해 어떤 방법을 했는지 설명하면서 그 방법들을 뒷받침하는 연구결과를 제시한다. 개인적인 의견으로는 1, 2, 3, 4장은 지극히 당연한 이야기를 했다.

멀티태스킹을 하면 안된다, 몰입을 해야한다, 수면의 질을 높이자, 긴 텍스트를 많이 읽자,.. 너무나도 당연하고 요즘 현대인들이 이 사실을 모르는 사람은 없다. 따분한 이야기를 계속하는 듯했다. 그래서 책을 4장을 읽은 후에 그만 읽고 다른 책을 읽을까도 고민했었다. 그러나 5장을 읽었을 때 많은 충격에 휩싸였다.

 

나는 평소에 수학 문제를 풀거나 다른 공부를 할 때 스스로에게 몇 시간동안 한정된 분량을 다하기로 결심하고 그것에만 온전히 집중해야한다고 생각했다. 즉, 딴 생각은 하면 안 된다고 생각했다. 그러나 오히려 이러한 딴 생각을 할 때 집중력이 좋아지며 머릿속에 있는 내용이 정리가 된다고 한다. 한 연구결과로 새로운 것을 배운 뒤 딴 생각을 할 때 새로운 것을 이해하기 위해 과거에 자신이 배웠던 내용을 연결시키면서 새로운 것을 이해하고 더 나아가 자신 만의 창의적인 인사이트를 만들어 낼 수 있다는 것이다. 그렇다면, 딴 생각이 도대체 뭐냐고 질문을 할 수 있을 것이다. 내가 이해한 것으로는 다음과 같다. '의식을 가지고 어떤 일을 열심히 하고 난 후에 산책이나 멍 때리기를 통해 의식이 없는 채로 뇌가 알아서 정리하도록 내버려두는 행위'. 이러한 행위를 하고 나면 오로지 외부 세계에만 정신없이 바쁘게 초점을 맞추어 살던 뇌가 현재 일어나고 있는 일을 소화할 수 있는 기회를 줌으로써 쉴 수 있도록 할 수 있다. 오히려 이러한 느슨한 연상 패턴이 독특한 통찰로 이어질 수 있다고 작가는 이 책을 통해 말하고 있다. 

 

그렇다면, 어떤 것들이 우리의 집중력을 계속해서 빼앗아 가고 있을까? 

가장 거대한 세력을 소개하자면 그건 바로 빅테크 기업들이다. '페이스북', '인스타그램', 'X', '구글' 등과 같은 빅테크 기업들은 우리의 정보를 이용해 조금 더 많이 자신의 앱이나 웹 사이트에 오래 머무를 수 있도록 한다. 평소 다른 일을 하고 있는 와중에도 알림을 수시로 날리거나 이메일을 보내 사람들의 관심을 끌어들이고 자신들의 앱에 접속시키게 함으로써 사람들이 온전하게 자신의 일에 집중할 수 없도록 만드는 것이 현재의 상황이다. 이것을 뒷받침하는 내용이 책에 존재하는데, 이 책의 9장에서 보면 '커먼 그라운드(Common Ground)'라는 이름의 과학자팀이 페이스북이 대중에게 공개하지 않은 숨은 자료를 전부 연구한 뒤 '우리의 알고리즘은 분열에 이끌리는 인간 두뇌의 특성을 이용하고 있으며 이를 그대로 놔둔다면 페이스북이 사용자의 관심을 끌고 플랫폼에 머무는 시간을 늘리고자 점점 더 분열적인 콘텐츠를 쏟아내게 되리라'고 말했다. 

앞서 말한 '사람들의 관심을 끌어들이고 자신들의 앱에 접속시키게..' 이것이 결국은 우리에게 자극적인 컨텐츠를 지속해서 제공 함으로써 웹이나 앱에 머무는 시간을 늘린다는 것이다. 그러면 대중들은 지속해서 편협한 사고관과 자극적인 컨텐츠에 물들여져서 평상 시에도 분노한 상태로 머물게 된다는 것이 이 책의 주장이다. 

 

이러한 주장이 나는 조금 급진적이라고 생각이 들지만 확실한 건 나도 인스타나 유튜브의 숏츠나 영상을 보고 난 뒤에 나의 할 일에 복귀하면 머릿속이 혼잡스럽고 내가 집중한다고 느끼는 시점까지의 시간이 오래걸리는 것 같다. 그리고 인스타의 알람이나 유튜브에서 내가 즐겨보는 채널의 알림이 뜨면 하던 일을 다 마무리하고 보는 것이 아니라 수시로 확인을 하는 것 같다. 

 

그래서 이러한 상황에서 빅테크 기업이 나아가야 할 방향성은 기업들이 알람을 수시로 보내는 것이 아니라 매일 아침이나 개인이 정해놓은 시간대에 한꺼번에 알람을 보내는 것이다. 마치 아침에 신문이 오는 것처럼. 이렇게 하면 알람이 수시로 오지 않아 하던 일에 온전히 몰입할 수 있게 된다. 또, 인스타그램이나 페이스북, X와 같은 SNS들은 온라인 상에서 사람들의 모습을 보게 하는 것이 아닌 실제 오프라인에서 사람들의 모습을 직접 보게 해주는 연결 프로그램을 코딩하여 사람들이 오프라인에서 활발하게 연결되는 상황을 만들어 주는 것이 좋다고 한다. 

 

흠... 나는 첫 번째 방법에는 어느 정도 동의를 하지만, 두 번째 방법에는 동의하지 못한다. 형태는 다르지만, 우리나라에서 만남 어플을 가졌다가 범죄에 악용되는 사례도 많고 만남 어플 또한 서로가 만나기 이전에는 사진을 통해 서로의 모습을 확인하게 될 텐데 이것 또한 보여지는 모습이기에 만남이 긍정적일 확률은 지극히 적다고 생각한다. 물론 어디까지나 배움이 얄팍한 나의 생각이지만, 이러한 점도 고려해야하는 것은 맞는 것 같다. 

 

그렇다면 우리 개인은 어떻게 하면 좋냐라고 하면 이 책에서는 6가지 방법을 소개한다. 

  1. 사전 약속을 이용해 지나친 전환을 멈춘다. - 미리 스스로에게 약속하여 sns의 사용을 금한다는 것이다. 
  2. 산만함에 반응하는 자신의 방식을 만들자. - 작가는 스스로에게 무엇이 중요한 것인지 물었다.
  3. 소셜미디어에 뺏기는 시간을 줄이자. 
  4. 딴 생각을 하는 시간을 정하고 이 시간을 허용하자.
  5. 수면의 질을 높이자.
  6. 자녀가 있는 가정이라면 자녀들에게 자유롭게 놀 수 있는 환경을 만들어주자.

나한테 6번은 그렇게 많이 중요하지 않지만 이 책의 후반부에서 가장 시간을 들여서 설명하는 것이 바로 자녀의 집중력이다. 이 책은 자녀가 있는 부모라면 이 부분이 너무너무너무 중요하게 느껴질 듯하다. 간략하게 저 6번이 나오게 된 경로를 설명하자면 내가 유치원이나 초등학교 저학년 시절에는 공부에는 정말 많이 신경 안 쓰고 놀았고 혼자 마을을 돌아다니면서 이것저것 체험했는데 요즘은 부모가 옆에서 지켜보지 않는 곳에서는 놀면 안된다는 인식이 팽배하다고 한다. 이러면 자녀가 자유롭게 자신의 의지에 따라 노는 것이 불가능해지고 이는 집중력의 저하로 이어진다고 한다. 왜냐면 자신의 의지에 따라 노는 것이 불가능해지니 위축되어 부모가 짜 놓은 판에서 의미없는 공부나 놀이를 하게 될 수도 있다는 것이다. 이렇게 되지 않게 하기 위해서는 자녀들에게 자유롭게 놀 수 있는 환경과 자신이 가치 있어하는 것들을 마음껏 할 수 있도록 해야한다는 것이다. 

 

저 6가지 방법을 내가 앞으로 살아가면서 얼마나 많이 실천할 수 있을 지는 솔직히 잘 모르겠지만, 실천할 수 있도록 노력이라도 하는 것이 중요한 것 같다. 

 

책에 대해 말하자면 이 책은 자녀가 있는 부모님들이 읽으면 정말 좋을 것 같고, 집중력이 예전같지 않다고 생각하는 분들도 읽으면 좋을 것 같다. 내가 쓴 글이 너무 중구난방처럼 느껴질 수 있을 것 같지만! 좋게 봐주시면 감사드리겠다. 

 

 

다음 번에는 경제랑 관련된 책으로 글을 쓸 생각이다. 

 

 

매개변수를 포인터로 선언하는 경우

1. 함수 간의 변수 공유를 통한 범용의 함수 정의 

 

> 함수와 함수 간의 지역변수를 공유하기 위하여 매개변수에 포인터를 사용한다. 

> 인수와 매개변수를 통하여 변수를 공유함으로써 코딩의 유연성(flexibilty)을 줄 수 있다.

> 매개변수를 통한 변수의 공유가 없다면 반환값을 사용하여 함수 간의 값을 전달을 해야하므로 자료형마다 값을 입력받는 수많은 함수를 만들어야한다. 또한 다양한 자료형을 한꺼번에 입력받기 위한 함수를 만들기는 매우 까다롭다.

 

2. 대량의 데이터를 함수 간의 공유

 

> 배열을 함수에 전달할 때 값의 복사 방식을 사용하면 복사본을 만들기 위한 주기억장치 할당으로 실행시간 및 주기억장치 낭비가 발생할 수 있다. 따라서 C언어에서는 기본적으로 배열의 시작 주소를 넘기는 방식을 사용한다. 

 

3. 동적 할당

 

> 프로그램에서는 배열 크기를 정할 때 최악의 경우를 대비하여 최대로 잡는다. 그러나 실제로 프로그램을 실행하는 동안 배열에 저장된 배열 원소 수가 예상보다 많이 작으면 이미 할당된 배열의 기억 공간 중 사용되지 않는 부분은 낭비된다. 이를 해결하기 위해 프로그램을 실행하면서 필요할 때마다 배열을 위한 기억 공간을 할당받고 필요 없어진 공간은 해제하는 동적 할당 방법을 사용할 수 있다. 이러한 동적 할당에 포인터가 사용된다. 

 

두 변수의 값을 바꾸는 함수 

#include <stdio.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)

void exchange_value(int *ref1, int *ref2);

int main()
{
	int v1 = 36, v2 = 98;

	printf("before exchange: v1 = %d, v2 = %d\n", v1, v2);
	exchange_value(&v1, &v2);
	printf("after exchange: v1 = %d, v2 = %d\n", v1, v2);

	return 0;
}

void exchange_value(int *ref1, int *ref2)
{
	int temp;

	temp = *ref1;
	*ref1 = *ref2;
	*ref2 = temp;
}

 

 

 

 

두 변수를 오름차순으로 정렬하기

#include <stdio.h>
#include <math.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)

void sort_value(int *ref1, int *ref2);

int main()
{
	int v1 = 36, v2 = 98;

	printf("v1? ");
	scanf("%d", &v1);
	printf("v2? ");
	scanf("%d", &v2);

	sort_value(&v1, &v2);
	printf("after exchange: v1 = %d, v2 = %d\n", v1, v2);

	return 0;
}

void sort_value(int *ref1, int *ref2)
{
	int temp;

	if (*ref1 > *ref2)
	{
		temp = *ref1;
		*ref1 = *ref2;
		*ref2 = temp;
	}
}

 

 

 

두 수의 몫과 나머지

#include <stdio.h>
#include <math.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)

void division(int *x, int *y, int a, int b);

int main()
{
	int n1 = 75, n2 = 8, quo, rem;

	division(&quo, &rem, n1, n2);
	printf("%d / %d = %d \n", n1, n2, quo);
	printf("%d %% %d = %d \n", n1, n2, rem);
}

void division(int *x, int *y, int a, int b)
{
	*x = a / b;
	*y = a % b;
}

'프로그래밍 > C,C++' 카테고리의 다른 글

포인터  (0) 2024.06.06
다양한 함수와 변수의 참조 범위  (0) 2024.05.30
문자열 처리  (0) 2024.05.28
인수 전달하는 함수  (0) 2024.05.28
인수 전달하지 않는 함수  (0) 2024.05.27

지금까지의 데이터를 저장하기 위하여 변수를 선언한 것은 선언할 때 명시한 변수의 자료형의 크기에 따라 주기억장치를 할당받는 것이고 변수를 사용한다는 것은 변수에 할당된 영역에 값을 저장하거나 저장된 값을 읽어서 사용한다는 것을 의미한다.

int var;
var = 10;
printf("%d\n", var);

 

포인터주소를 저장하기 위한 변수다. 

포인터를 사용하는 이유는 값을 간접참조(우회적으로 참조)하기 위한 것이다.

예시를 보자. 아래 예시는 위의 예시와는 다르다.(위의 예에서 var을 직접 사용하지 않고 *ptr을 사용하여 간접 참조한다.)

int *ptr;
ptr = &var;
printf("%d\n", *ptr);

 

여기서 포인터 연산자(*)와 주소 연산자(&)의 의미를 배워보자.

 

포인터 

char *p_chr;
int *p_int;
double *p_dbl;

 

char *p_chr; >> p_chr이 가리키는 곳에 char형 값이 있다. 

char *p_int; >> p_int이 가리키는 곳에 int형 값이 있다. 

char *p_dbl; >> p_dbl이 가리키는 곳에 double형 값이 있다. 

 

주의!!

주소의 크기는 같으므로 포인터의 크기는 같다.

printf("문자형과 포인터의 크기: %d, %d\n", sizeof(char), sizeof p_chr);
printf("정수형과 포인터의 크기: %d, %d\n", sizeof(int), sizeof p_int);
printf("실수형과 포인터의 크기: %d, %d\n", sizeof(double), sizeof p_dbl);

// 문자형과 포인터의 크기: 1, 4
// 정수형과 포인터의 크기: 4, 4
// 실수형과 포인터의 크기: 8, 4

 

>> 포인터의 크기는 모두 4바이트(32비트 컴파일러일 경우)로 같다. 이유는 주소를 표현하는 크기는 같기 때문이다. 

>> 예를 들자면 건물의 크기는 다양하지만, 주소의 길이는 비슷한 것과 같은 이치이다. 

 

주소연산자 (&)

int amt, *p_amt;

amt = 100;
p_amt = &amt;

 

일반 변수 amt를 선언하고 포인터 연산자 *와 연산자 &를 사용하여 amt 변수의 시작주소를 p_amt에 저장하는 예시이다.

밑에 그림은 어떻게 흐름이 이어나가는건지 그림으로 나타낸 것이다. 

amt의 시작주소가 1004인데 그거를 p_amt = &amt를 통해서 amt의 시작주소를 p_amt에 저장한다.

 

 

포인터 연산자 (*)

지금 현재 p_amt에는 amt의 시작주소인 1004가 저장되어 있는 것이다. 

그렇다면 p_amt가 아닌 p_amt가 가리키는 곳을 참조하고 싶을 때는 포인터 연산자 (*)를 사용해야한다.

포인터는 자료의 시작주소만을 저장하고 있고 포인터의 자료형 크기에 따라 마지막 주소가 결정된다.

즉 p_amt는 정수형 포인터이고 4바이트를 참조하므로 시작주소는 1004번지이고 끝 주소는 1007번지가 된다.

*p_amt는 1004-1007번지의 값을 읽어오는 수식으로 p_amt로 amt를 간접참조한다. 

따라서 amt == *p_amt 수식은 참이다. 

 

 

'프로그래밍 > C,C++' 카테고리의 다른 글

포인터 예제  (0) 2024.06.11
다양한 함수와 변수의 참조 범위  (0) 2024.05.30
문자열 처리  (0) 2024.05.28
인수 전달하는 함수  (0) 2024.05.28
인수 전달하지 않는 함수  (0) 2024.05.27

값에 의한 호출(call-by-value)

f_sum() 함수를 호출할 때 a값이 전달되어 begin에 저장되며, b 값이 전달되어 end에 저장된다.

#include <stdio.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)

int f_sum(int begin, int end);

int main()
{
	int a, b, sum;    //지역변수

	printf("a ~ b까지의 합 구하기 \n");
	printf("a는? ");
	scanf("%d", &a);
	printf("b는? ");
	scanf("%d", &b);

	sum = f_sum(a, b); //함수호출

	printf("\n%d ~ %d의 합은 %d", a, b, sum);

	return 0;
}

int f_sum(int begin, int end)
{
	int i, sum;

	sum = 0;
	for (i = begin; i <= end; i++)
	{
		sum += i;
	}

	return sum;
}

 

f_sum()함수에서 main()의 인수 a를 전달받은 begin 변수는 a와 같은 값을 가진다. 

f_sum()함수에서 return sum; 직전에 begin = begin * 2;를 실행하여 begin 값을 변경하면 main()의 a값도 변할까? 

a와 begin은 서로 다른 함수에서 선언하여 다른 기억장소를 사용하기 때문에 a는 변하지 않는다. 

f_sum() 함수를 int f_sum(int a, int b)로 정의하여도 매개변수 a는 동명이인에 해당하므로 다른 기억장소를 사용한다. 

 

이 방식은 호출된 함수에서 자신을 호출한 함수의 인수를 절대로 변경할 수 없으므로 함수를 호출할 때 마음 놓고 자신의 정보를 전달할 수 있다. 이 '함수 간 독립성 보장'이라는 특징 때문에 함수 호출 시 기본적으로 사용하는 인수 전달 방식이 '값에 의한 호출'이다.

 

이해를 돕기 위한 예시

내 노트를 복사 >>> 각자 내용이 같은 노트를 갖게 된다.

 

 

코드 예시

#include <stdio.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)
#define N 5

int f_even(int no);

int main()
{
	int i, marble[N] = { 5, 4, 2, 3, 7 };

	for (i = 0; i < N; i++)
	{
		if (f_even(marble[i]) == 1)
		{
			printf("%d: 홀수\n", marble[i]);
		}

		else
		{
			printf("%d: 짝수\n", marble[i]);
		}
	}

	return 0;
}

int f_even(int no)
{
	if (no % 2 != 0)
	{
		return 1;
	}

	else
	{
		return 0;
	}
}

 

주소에 의한 호출(call-by-value)

배열 전체를 함수에 전달할 때는 주소에 의한 호출 방식만 사용한다.

원소가 천 개인 배열 전체를 값에 의한 호출 방식으로 전달한다고 가정해보자.

인수인 배열의 원소 개수만큼 값을 저장할 매개변수의 기억장소가 필요하고, 배열 원소 순서대로 매개변수에 값을 저장하는데 시간이 걸린다. 

배열은 대량의 자료를 저장하는 데 사용하므로 이 배열을 값에 의한 호출로 전달한다면 추가적 기억장소와 값 복사로 인한 자원 낭비가 데이터 양에 비례하여 커진다. 

그래서 배열은 원본을 공유하는 주소에 의한 호출 방식을 사용한다. 

 

#include <stdio.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)
#define N 5

int f_tot(int ary[N]);

int main()
{
	int kor[N] = { 45, 34, 43, 33, 48 };

	printf("총계: %d \n", f_tot(kor));

	return 0;
}

int f_tot(int ary[N])
{
	int i, sum;

	sum = 0;
	for (i = 0; i < N; i++)
	{
		sum += ary[i];
	}

	return sum;
}

 

 

배열 인수: 차원과 상관없이 배열명만 사용 

>> 배열명은 배열 시작 주소이므로 결국 주소를 전달하는 방식 

 

배열 매개변수 선언: 전달되는 배열의 차원에 맞게 배열 선언 

 

주의

- 배열은 함수 간에 같은 기억장소를 공유하므로 호출된 함수 f_tot()에서 ary배열 원소를 변경하면 main()의 kor 배열 원소가 변경된다.  >> 함수에서 배열 내용을 변경한 후 배열을 반환할 필요가 없다.

 

- 매개변수 배열 선언 시 

 1차원 배열이라면 int ary[N] 대신 int ary[ ]처럼 원소수 생략 가능

 2차원 배열이라면 int b[5][7]대신 int b[ ][7]처럼 행 개수 생략 가능

 

- f_tot() 함수는 원소 개수가 N개일 때만 사용할 수 있다. 원소 개수와 상관없이 총계를 구하는 함수는 나중에 배울 예정.

 

 

배열을 전달하여 모든 원소를 두 배로 변경하기 

 

#include <stdio.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)
#define N 5

void f_double(int ary[N]);

int main()
{
	int i, kor[N] = { 45, 34, 43, 33, 48 };

	f_double(kor);

	for (i = 0; i < N; i++)
	{
		printf("%4d", kor[i]);
	}

	return 0;
}

void f_double(int ary[N])
{
	int i;

	for (i = 0; i < N; i++)
	{
		ary[i] *= 2;
	}
}

 

 

예시

노트 원본을 빌려주므로 노트는 공유하는 한 권만 있게 되는 경우

 

 

 

함수 호출 시 결과를 저장할 빈 배열을 추가로 전달하기

#include <stdio.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)
#define N 5

void f_twice(int a[N], int a_twice[N]);
void f_print(int ary[N]);

int main()
{
	int i, kor[N] = {45, 34, 43, 33, 48};
	int kor_twice[N];

	f_twice(kor, kor_twice);
	f_print(kor);
	f_print(kor_twice);
}

void f_twice(int a[N], int a_twice[N])
{
	int i;

	for (i = 0; i < N; i++)
	{
		a_twice[i] = a[i] * 2;
	}
}

void f_print(int ary[N])
{
	int i;

	for (i = 0; i < N; i++)
	{
		printf("%d ", ary[i]);
	}

	printf("\n");
}

 

void형 함수면 return; 생략가능

 

 

#include <stdio.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)

double get_average(int ary[], int n);

int main()
{
	int a[4] = { 92, 80, 75, 93 };
	int b[3] = { 88, 57, 81 };

	printf("a 평균: %5.1f \n", get_average(a, sizeof(a) / sizeof(a[0])));
	printf("b 평균: %5.1f \n", get_average(b, sizeof(b) / sizeof(b[0])));

	return 0;
}

double get_average(int ary[], int n)
{
	int i, sum;

	sum = 0;
	for (i = 0; i < n; i++)
	{
		sum += ary[i];
	}

	return (double) sum / n;
}

'프로그래밍 > C,C++' 카테고리의 다른 글

포인터 예제  (0) 2024.06.11
포인터  (0) 2024.06.06
문자열 처리  (0) 2024.05.28
인수 전달하는 함수  (0) 2024.05.28
인수 전달하지 않는 함수  (0) 2024.05.27

문자 선언

//문자 1개
char alpha = 'C';
// 문자열 1개
char id[5] = "Nabi";

 

Nabi는 4글자인데 id[5]로 5글자를 저장하겠다고 코드를 작성하면

'N' 'a' 'b' 'i' '\0'로 저장이 된다. 

 

// 문자열 3개
char fr[3][6] = {"Jaeil", 
		"Doori", 
                "Gosu"}

 

마찬가지로 행의 길이가 6글자로 저장된다고 했는데 5글자, 4글자로 문자열이 저장되어있다.

이 같은 경우에도 \0이 남는 자리에 저장이 된다. 

 

원소 호출

 

 

원소 호출을 할 때는 2차원 배열을 호출할 때 하는 것처럼 하면 된다. 

 

 

 

문자열 단위의 입출력

 

문자열의 시작주소

 

char형 1차원 배열일 때

배열명: 문자열 시작 주소

// 문자열 1개
char id[5] = "Nabi";

 

id: 문자열 시작 주소 (포인터)

 

 

 

char형 2차원 배열일 때

배열명[행첨자] : 해당 행 문자열 시작 주소

// 문자열 3개
char fr[3][6] = {"Jaeil", 
		"Doori", 
                "Gosu"}

 

- fr[0] : 1번째 문자열 시작 주소

- fr[1] : 2번째 문자열 시작 주소

- fr[2] : 3번째 문자열 시작 주소

 

 

 

기억!!

배열명은 배열 시작 주소이며 배열 시작 위치를 가리킨다!

 

 

단순 문자열을 출력하기 위한 형식 

문자열 입력

scanf("%s", 문자열 저장 시작 주소);

  • 키보드에서 입력되는 문자열을 지정한 주소의 기억장소부터 차례대로 저장함.
  • 배열에 남는 공간이 있어야 입력 문자열 뒤에 널 문자가 저장됨.
  • ex) scanf("%s", id); , scanf("%s", fr[2])  (+&가 없다!)

문자열 출력

printf("%s", 문자열이 저장된 시작 주소);

  • 시작 주소로부터 저장된 문자를 연속으로 출력하되 널 문자를 만나면 출력을 끝냄.
  • ex) printf("%s", id);, printf("%s", fr[2])

 

 

주의!

문자열 시작 주소와 %를 이용한 문자열 출력은 널 문자('\0')를 만나야 출력이 끝난다. 

다음 sur 배열은 배열 원소 수가 문자열의 길이 즉, 실제 문자 개수와 똑같다.

그러므로 널 문자가 저장되지 않기에 이상한 결과가 나올 수 있다.

 

참고로, 비주얼 스튜디오에서 위의 코드를 '*.c'와 같이 C언어 소스 파일로 저장하면 실행이 된다.

하지만 C++언어는 배열에 널 문자가 들어갈 공간이 없으면 오류가 되어 실행 자체가 되지 않는다.

 

 

 

 

문자열 처리 함수

 

strcpy() - 문자열 복사

 

 

strcmp() - 두 문자열의 크기를 비교

 

 

 

공백이 있는 문자열 입력

 

 

예시1

#include <stdio.h>
#include <string.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)

int main()
{
	char grade, name[10], reply[10];
	char correct[10] = "로딩중";

	printf("받고 싶은 C언어 등급은? ");
	scanf("%s", &grade);

	printf("\n%c를 받기 위해 노력 중이군요!", grade);

	printf("\n이름은? ");
	scanf("%s", &name);

	printf("%s님 반갑습니다!", name);

	printf("\n문제: 세상에서 가장 느린 중학교는? ");
	scanf("%s", &reply);

	if (strcmp(reply, correct) == 0)
	{
		printf("맞았습니다!");
	}

	else
	{
		printf("틀렸습니다! 정답은 %s!\n", correct);
	}

	return 0;
}

 

예시2

#include <stdio.h>
#include <string.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)
#define N 5

int main()
{
	char std[N][10] = { "최고수", "진재일", "강인", "나태희", "유명인" };

	int i, quiz[N] = { 10, 9, 8, 7, 9 };

	for (i = 0; i < N; i++)
	{
		printf("%s   %d\n", std[i], quiz[i]);
	}

	return 0;
}

 

 

예시3

#include <stdio.h>
#include <string.h>
#pragma warning(disable: 4996)
#pragma warning(disable: 6031)
#define N 5

int main()
{
	char std[N][6] = { "itsme", "ace", "iam", "myid", "snow"};
	char input[6];
	int i;

	printf("아이디는? ");
	scanf("%s", &input);

	for (i = 0; i < N; i++)
	{
		if (strcmp(input,std[i]) == 0)
		{
			printf("%s님 반갑습니다.", input);
			break;
		}
	}

	if (i == N)
	{
		printf("없는 아이디입니다.");
	}


	return 0;
}

'프로그래밍 > C,C++' 카테고리의 다른 글

포인터  (0) 2024.06.06
다양한 함수와 변수의 참조 범위  (0) 2024.05.30
인수 전달하는 함수  (0) 2024.05.28
인수 전달하지 않는 함수  (0) 2024.05.27
자료 배열 2 (9장)  (0) 2024.05.27

+ Recent posts