Computer Architecture와 Organization.md

Computer Architecture와 Organization

Computer Architecture : 프로그래머가 명확히 알 수 있는 시스템 속성들, 프로그램의 논리적 실행에 직접적인 영향을 끼친다.

  • 인스트럭션 셋, 자료형을 표현하는데 사용되는 비트 수, I/O메커니즘, 메모리 어드레싱 기술

 

Computer Organization : 아키텍쳐 사양을 구현하는 operational unit들과 그의 상호 연결

  • 하드웨어 사양, 제어 신호(control signal), 컴퓨터와 주변기기 간의 인터페이스, 사용된 메모리 기술(ex. SRAM, DRAM etc..)

 

 

Structure

구성 요소들이 서로 연관 되어 있는 방법

  • 계층적 시스템(Hierarchical system) : 상호 연관된 subsystem들의 집합. 복잡한 계층적 시스템은 설계와 그에 대한 명세가 필수적이며, 설계자는 한 번에 하나의 계층만을 설계하면 된다.

 

 

Funtion

컴퓨터가 수행하는 기본적인 4가지 기능

  • Data processing(데이터 처리) : 데이터는 수많은 형식을 다루고, 처리 요구 사항의 범위가 넓다.

  • Data storage(데이터 저장) : Short-term, Long-term

  • Data movement(데이터 이동)

    • I/O(입출력) : 컴퓨터와 직접 연결된 주변기기로 부터 받거나 줄 때
    • 데이터 통신 : 데이터를 원거리 기기와 먼거리에서 주고 받을 때
  • Data control(데이터 제어) : 제어장치(control unit)는 컴퓨터 자원을 관리하고, 명령에 대한 응답으로 기능적 부분의 성능을 조정한다.

 

 

CPU

주요 구성 요소

  • Control Unit (CU; 제어장치) : CPU 및 컴퓨터의 작동을 제어
  • Arithmetic and Logic Unit (ALU; 산술 논리 장치) : 컴퓨터의 데이터 처리 기능을 수행
  • Registers : CPU 내부에 저장 공간 제공
  • CPU Interconnection : control unit, ALU 그리고 레지스터 사이의 통신을 제공하는 메커니즘

 

 

CU의 구성

  • Microprogrammed Implementation(마이크로프로그램에 의한 구현)

    • 순차적인 명령어, 레지스터 및 디코더, 기억 장치 등으로 구성
    • 동작 방식을 수정할 때 기억장치의 프로그램을 바꾸기만 하면 되므로 융통성이 있다.
  • Hardwired Logic Implmentation(논리회로 설계 방식에 의한 구현)

    • 빠르게 동작하나, 동작 방법이 바뀌면 재설계 해야한다.

 

 

Single Core Computer

구성 요소

  • Control Unit : CPU 및 컴퓨터의 작동을 제어
  • Main Memory : 데이터 저장
  • I/O : 컴퓨터와 외부 환경 사이의 데이터 이동
  • System Interconnection - CPU, main memory, I/O간의 통신을 제공하는 메커니즘

 

 

Multicore Computer

멀티코어 컴퓨터에서의 processor, core, cpu 개념

  • Processor

    • 물리적으로 하나 또는 여러 코어가 포함되어있는 하나의 칩
    • 명령어를 해석하고 실행하는 구성요소
    • 여러개의 코어를 가진 프로세서를 멀티코어 프로세서라고 함
  • Core

    • 프로세서 칩 상의 각각의 처리 유닛
    • 단일 CPU 시스템에서의 CPU와 기능적으로 동일함
  • Central processing unit (CPU)

    • 컴퓨터에서 명령어를 불러오고 수행하는 부분
    • ALU, control unit, register로 구성
    • 단일 처리 시스템에서 프로세서라고 부름

시간복잡도?

모든 알고리즘은 수행하는데 필요한 시간이 있다. 시간복잡도는 다음과 같이 정의할 수 있다.

알고리즘을 수행하는데 필요한 총 시간

 

알고리즘의 수행시간에 영향을 끼치는 요인들은 다음과 같다.

  1. 실행되는 프로세서가 단일프로세서인지 멀티프로세서인지
  2. 운영체제가 32비트인지 64비트인지
  3. 컴퓨터의 읽고 쓰는 속도
  4. 산술연산, 논리연산, 반환 값과 할당 작업 등
  5. 입력데이터

 

알고리즘의 시간복잡도를 계산할 때, 입력데이터를 제외한 나머지 것들은 고려하지 않는다(하드웨어에 달린 문제이기에). 프로그램이 입력데이터에 따라 어떻게 수행되는 지에 초점을 맞춘다.

컴퓨터 시스템마다 전부 다르기 때문에 시스템 설정(1,2,3,4)에 기반한 알고리즘 시간복잡도 계산은 매우 복잡하다. 그렇기 때문에 여기서는 특정한 시스템 모델로 가정하고 계산하자(점근적 표기법은 다음에 알아보자).

시간 복잡도 계산을 위한 모델을 다음과 같이 정의해보자

  1. 싱글 프로세서
  2. 32비트 운영체제
  3. 순차적 실행
  4. 산술 연산과 논리 연산에 1 단위 시간 필요
  5. 할당과 반환값에 1 단위 시간 필요
  6. 읽고 쓰는 연산에 각각 1 단위 시간 필요

이제 이 모델로 시간 복잡도를 계산해보자

 

예시 1

int sum(int a, int b){
    return a + b;
}

위의 코드에서 a+b를 수행하는데 1 단위 시간이 필요하고, 값을 반환하는데 1 단위 시간이 필요하다. 이 코드를 수행하는데 총 2 단위 시간이 필요하며, 이 값은 입력 값 a, b에 상관없이 일정하다.


입력 값에 상관 없이 수행하는데 필요한 시간이 변하지 않을 때, 이 시간 복잡도를 상수 시간 복잡도(Constant Time Complexity) 라고 한다.

 

 

예시 2

int sum(int A[], int n){
    int sum = 0, i;         // 1
    for(i = 0; i < n; i++)	// 1 + (n+1) + n
    	sum = sum + A[i];   // 2n
    return sum;             // 1
}                           // total : 4n + 4

sum에 0을 저장하는데 1 단위 시간

i = 0 을 저장하는데 1 단위 시간

i < n 을 비교(논리 연산) 1 단위 시간이 n+1번

i++을 수행하는데 1 단위 시간이 n번

sum = sum + A[i]를 수행하는데 2 단위 시간이 n번

sum을 반환하는데 1 단위 시간

총 4n+4시간이 걸린다. 이는 고정된 값이 아니며 입력 값인 n에 의해 바뀐다.


입력 값이 증가함에 따라 시간의 양이 선형적으로 증가할 때, 이 시간 복잡도를 선형 시간 복잡도(Linear Time Complexity)라고 한다.


'Data Structure' 카테고리의 다른 글

Space Complexity - 공간복잡도  (1) 2018.04.18

어느 알고리즘 이든 다음과 같은 이유들로 컴퓨터의 메모리를 필요로 한다.

  1. 프로그램 명령어 저장
  2. 상수 저장
  3. 변수 저장
  4. 기타 등등

알고리즘의 공간복잡도는 다음과 같이 정의할 수 있다.

알고리즘이 수행되는데 필요한 메모리의 총량

 

프로그램이 실행될 때 보통 세가지 이유로 컴퓨터 메모리를 사용한다.

  1. Instruction Space: 컴파일된 명령어들을 저장하는 메모리의 양
  2. Environmental Stack: 함수 호출시 부분적으로 실행 된 함수의 정보를 저장하는 데 사용되는 메모리의 양
  3. Data Space: 모든 변수와 상수를 저장하는 메모리의 양

알고리즘의 공간복잡도를 분석할 때, 보통 Instruction Space와 Environmental Stack은 무시하고 Data Space만을 고려한다. 변수, 상수, 구조체 등이 저장되는데 필요한 메모리만을 계산하겠다는 뜻이다.

 

예시 1

int square(int a) {
    return a*a;
}

위 코드에서는 변수 'a'를 저장하는데 2바이트, return value를 위해 2바이트가 사용된다. input값 'a'에 대해 4바이트가 고정적으로 필요하다.


알고리즘이 어느 input value에 대해 항상 고정된 공간을 필요로 할 때, 이를 상수 공간 복잡도(Constant Space Complexity)라 한다.

 

예시 2

int sum(int A[], int n){
	int sum = 0, i;
	for(i = 0; i < n; i++)
		sum = sum + A[i];
	return sum;
}

A[]를 저장하기 위해 'n*2' 바이트, n을 저장하기 위해 2바이트, 지역변수 sum, i를 위해 각각 2바이트씩, return value를 위해 2바이트가 필요하다. 즉, 이 코드를 수행하기 위해 '2n + 8' 바이트가 필요하며 인풋인 n에 메모리 양이 의존하게 된다.


알고리즘이 어느 input value가 증가함에 따라 필요한 공간이 선형적으로 증가하는 것을 선형 공간 복잡도(Linear Space Complexity)라고 한다.

 


'Data Structure' 카테고리의 다른 글

Time Complexity - 시간복잡도  (1) 2018.04.19

IntelliJ에서 Junit을 사용하는 간단한 방법을 알아보자.


먼저 간단한 클래스를 만든다.

간단한 King 클래스



프로젝트에 테스트 클래스를 담을 디렉토리를 만든다.



'File > Project Structure > Module' 로 가서 'tests' 디렉토리 선택 후 Mark as에서 'Tests'를 선택하고 적용한다.



적용후 변경된 tests 아이콘




King 클래스에 커서를 두고 Alt + Enter 키를 누르고 Create Test를 누른다.




Testing library에서 JUnit4 를 선택하고 생성할 테스트 메소드를 체크하고 OK 버튼을 누른다.



위와 같이 테스트 클래스가 생성되나 JUnit 라이브러리가 클래프 패스에 추가되어 있지 않기 때문에 오류가 난다.



빨간 글씨의 junit에 커서를 두면 빨간 전구가 나타나는데 이를 클릭하고, 'Add 'JUnit4' to classpath'를 선택하여 JUnit4를 클래스 패스에 추가한다.



둘중 무엇을 선택해도 상관없으나 프로젝트에 라이브러리를 따로 포함시켰다.





이제 간단한 테스트 코드를 작성하고



마우스 오른쪽 버튼을 누르고 실행해보면




테스트가 성공적으로 수행되었다.

아마존에서 제공하는 Alexa를 raspberry pi에 올려보자

https://github.com/ewenchou/alexa-client

위 URL을 따라가서 지시에 따라 alexa client를 사용해보도록 한다.


test_ask.py 파일은 영어로 된 wav파일을 요청하면 그에 맞는 alexa의 대답을 영어로된 wav파일로 반환해준다.

여기서 입력과 출력을 한글로 변경해보도록 하자.


먼저 한글 음성, 영어 음성을 각각 text로 변환시켜줄 STT와 텍스트를 음성으로 변환 시켜줄 TTS 그리고 번역이 필요하다.

각 부분에 대해 사용할 것은 다음과 같다.

STT : Google Cloud Speech API

TTS : Naver 음성합성 API

번역 : Naver 기계번역 API


Google Cloud Speech API

위 주소의 지시를 따라 debian에서 Google Cloud SDK 환경을 설치한다. 환경이 준비 되었다면 다음 URL을 따라서 Google Cloud Speech API를 사용하는 법에 대해 배워 보고, 제대로 작동되는지 예제를 다뤄보라.

https://cloud.google.com/speech/docs/getting-started


Naver API

TTS 설명 및 예시


Translation 설명 및 예시

https://developers.naver.com/docs/labs/translator/


이제 준비가 다 되었다. 한글로 말하면 한글로 대답해주는 나만의 korean Alexa를 python 코드로 구현해 보자.


korean Alexa

def transcribe_file_kor(speech_file):
    """Transcribe the given audio file."""
    
    speech_client = speech.Client()

    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()
        audio_sample = speech_client.sample(
            content=content,
            source_uri=None,
            encoding='LINEAR16',
            sample_rate_hertz=16000)

    alternatives = audio_sample.recognize('ko-KR')
    for alternative in alternatives:
		return alternative.transcript
		
def transcribe_file_eng(speech_file):
    """Transcribe the given audio file."""
    
    speech_client = speech.Client()

    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()
        audio_sample = speech_client.sample(
            content=content,
            source_uri=None,
            encoding='LINEAR16',
            sample_rate_hertz=16000)

    alternatives = audio_sample.recognize('en-US')
    for alternative in alternatives:
		return alternative.transcript

 이 코드는 Google Cloud Speech API를 사용하여 각각 한글로 된 음성파일을 한글 텍스트로, 영어로 된 음성파일을 영어 텍스트로 변환 시켜주는 코드이다. 



def translateKorToEng(korean_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(korean_string.encode("utf-8"))
	data = "source=ko&target=en&text=" + encText
	url = "https://openapi.naver.com/v1/language/translate"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode("utf-8"))
	rescode = response.getcode()
	if(rescode==200):
		response_body = json.loads(response.read().decode('utf-8'))
		translated_eng_str = response_body["message"]["result"]["translatedText"]
		return translated_eng_str
	else:
		print("Error Code:" + rescode)
		

def translateEngToKor(english_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(english_string.encode("utf-8"))
	data = "source=en&target=ko&text=" + encText
	url = "https://openapi.naver.com/v1/language/translate"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode("utf-8"))
	rescode = response.getcode()
	if(rescode==200):
		response_body = json.loads(response.read().decode('utf-8'))
		translated_kor_str = response_body["message"]["result"]["translatedText"]
		return translated_kor_str
	else:
		print("Error Code:" + rescode) 

 위 코드는 Naver 기계번역 API를 이용하여 한글을 영어로, 영어를 한글로 번역해주는 코드이다. client_id, client_secret 변수에는 자신이 할당 받은 id 와 secret을 적어 넣으면 된다.



def koreanTextToSpeech(korean_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(korean_string.encode("utf-8"))
	data = "speaker=mijin&speed=0&text=" + encText;
	url = "https://openapi.naver.com/v1/voice/tts.bin"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode('utf-8'))
	rescode = response.getcode()
	if(rescode==200):
		print("TTS mp3")
		response_body = response.read()
		with open('response_audio_file_path.mp3', 'wb') as f:
			f.write(response_body)
	else:
		print("Error Code:" + rescode)

 위 코드는 한국어 TTS코드로 Naver 음성합성 API를 이용하여 한글 텍스트 파일을 요청하면 한국어 음성파일을 반환하는 코드이다. 마찬가지로 자신의 client_id 와 client_secret을 넣어주면 된다. "output_audio_file_path.mp3" 에는 음성파일을 반환받기 원하는 경로와 파일명을 정해주면 된다.



def askToAlexa():
    alexa = AlexaClient()
    input = 'your_request_audio_path.wav'
    save_to = 'your_response_audio_path.mp3'
    alexa.ask(input, save_to=save_to)
    print "Response from Alexa saved to {}".format(save_to) 

 마지막으로 영어 음성파일을 Alexa에게 전달하고 그에 대한 답변을 음성파일로 받는 함수이다.  input과 save_to에 각각 자신의 요청파일과 반환받기 원하는 파일의 경로와 파일명을 넣으면 된다. 


이제 조각 들을 모두 모았으니 하나로 합쳐보자!


# -*- coding: utf-8 -*-
import io
import sys
import os
import json
from six.moves import urllib
from alexa_client import AlexaClient
from google.cloud import speech

def transcribe_file_kor(speech_file):
    """Transcribe the given audio file."""
    
    speech_client = speech.Client()

    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()
        audio_sample = speech_client.sample(
            content=content,
            source_uri=None,
            encoding='LINEAR16',
            sample_rate_hertz=16000)

    alternatives = audio_sample.recognize('ko-KR')
    for alternative in alternatives:
		return alternative.transcript
		
def transcribe_file_eng(speech_file):
    """Transcribe the given audio file."""
    
    speech_client = speech.Client()

    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()
        audio_sample = speech_client.sample(
            content=content,
            source_uri=None,
            encoding='LINEAR16',
            sample_rate_hertz=16000)

    alternatives = audio_sample.recognize('en-US')
    for alternative in alternatives:
		return alternative.transcript
		
		
def translateKorToEng(korean_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(korean_string.encode("utf-8"))
	data = "source=ko&target=en&text=" + encText
	url = "https://openapi.naver.com/v1/language/translate"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode("utf-8"))
	rescode = response.getcode()
	if(rescode==200):
		response_body = json.loads(response.read().decode('utf-8'))
		translated_eng_str = response_body["message"]["result"]["translatedText"]
		return translated_eng_str
	else:
		print("Error Code:" + rescode)
		

def translateEngToKor(english_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(english_string.encode("utf-8"))
	data = "source=en&target=ko&text=" + encText
	url = "https://openapi.naver.com/v1/language/translate"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode("utf-8"))
	rescode = response.getcode()
	if(rescode==200):
		response_body = json.loads(response.read().decode('utf-8'))
		translated_kor_str = response_body["message"]["result"]["translatedText"]
		return translated_kor_str
	else:
		print("Error Code:" + rescode)
	
	
	
def koreanTextToSpeech(korean_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(korean_string.encode("utf-8"))
	data = "speaker=mijin&speed=0&text=" + encText;
	url = "https://openapi.naver.com/v1/voice/tts.bin"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode('utf-8'))
	rescode = response.getcode()
	if(rescode==200):
		print("TTS mp3")
		response_body = response.read()
		with open('korean_alexa.mp3', 'wb') as f:
			f.write(response_body)
	else:
		print("Error Code:" + rescode)
	
	
"""This test will send a pre-generated audio file in the `tests` directory
to AVS, and saves it as `/tmp/test1.mp3`."""
def askToAlexa():
    alexa = AlexaClient()
    input = 'after_srate_conv.wav'  #'{}/1.wav'.format(TESTS_PATH)
    save_to = 'response_alexa.mp3'
    alexa.ask(input, save_to=save_to)
    print "Response from Alexa saved to {}".format(save_to)


if __name__ == '__main__':

	# 환경 변수 설정
	os.system("export GOOGLE_APPLICATION_CREDENTIALS=\"Your_Google_Service_Account_Key_Path.json\"")
	
	# 인코딩 설정
	reload(sys)
	sys.setdefaultencoding('utf-8')
	
	# 녹음
	os.system("arecord -D plughw:1,0 -f S16_LE -c1 -r16000 -d 3 input.wav")
	print("recording complete!")
	
	# STT 한글
	input_kor_str = transcribe_file_kor('input.wav')
	print(input_kor_str)
	
	# 한글을 영어로 번역
	input_eng_str = translateKorToEng(unicode(input_kor_str))
	print(input_eng_str)
	
	# 영어 TTS
	os.system("espeak -w before_srate_conv.wav \""+input_eng_str+"\"")
	os.system("sox before_srate_conv.wav -r 16000 after_srate_conv.wav")
	print("TTS and srate convert completed")
	
        # alexa
	askToAlexa()
	
	# 영어음성 STT
	os.system("sox response_alexa.mp3 -r 16000 response_alexa_converted.wav")
	output_eng_str = transcribe_file_eng('response_alexa_converted.wav')
	print(output_eng_str)
	
	# 영어문장을 한글로 번역
	output_kor_str = translateEngToKor(output_eng_str).encode("utf-8")
	print(output_kor_str)
	
	# 한글 TTS
	koreanTextToSpeech(unicode(output_kor_str))
	
	# 한글 음성 출력
	os.system("mpg321 korean_alexa.mp3") 

자 이제 한글로 얘기하면 한글로 대답해주는 코드가 완성되었다. 미국 대통령이 누군지 물어보자.







+ Recent posts