CPU가 4바이트 정수에 접근할 때, 캐시 히트를 하지 못하면 간단히 캐시에 4바이트 정수를 저장하면 된다고 생각함.그러나 그렇지 않음.캐시와 메모리 상호 작용의 기본 단위: 캐시 라인프로그램이 어떤 데이터에 접근하면 다음에는 인접한 데이터에 접근할 가능성이 높으므로 접근해야 할 데이터만 캐시에 저장하지 않음.해당 데이터가 있는 곳의 ‘묶음’ 데이터를 캐시에 저장함.이를 캐시 라인 이라고 함.묶음 데이터는 일반적으로 64바이트임.캐시와 메모리 사이의 상호 작용에 대한 세부 내용은 다중 스레드 프로그래밍이고, 일반인이라면 생각해 낼 수 없음. → 매우 흥미로운 문제를 가져옴.첫 번째 성능 방행자: 캐시 튕김 문제atomic a;void threadf(){ for (int i = 0; i atomic a;v..
최신 컴퓨터 시스템에서 프로그램이 메모리에 접근할 때 캐시의 적중률이 매우 중요함.캐시 친화적인 프로그램을 작성하여 캐시 적중률을 향상 시켜야 함. 프로그램 지역성의 원칙지역성이란 프로그램이 ‘매우 규칙적으로’ 메모리에 접근한다는 의미임.프로그램이 메모리 조각에 접근하고 나서 이 조각을 여러 번 참조하는 경우 → 시간적 지역성(temporal locality) 라고 함.시간적 지역성은 캐시 친화성이 매우 높음.데이터가 캐시에 있는 한 메모리에 접근하지 않아도 반복적으로 캐시의 적중이 가능함.프로그램이 메모리 조각을 참조할 때, 인접한 메모리도 참조할 수 있음. → 공간적 지역성(spatial locality) 라고 함.캐시가 적중하지 않으면 메모리의 데이터를 캐시에 적재해야 함.일반적으로 요청한 메모리의..
프로그램이 실행되는 동안 CPU는 메모리와 빈번하게 상호작용 해야 함.캐시, 어디에나 존재하는 것폰 노이만 구조에서는 CPU가 실행하는 기계 명령어와 명령어가 처리하는 데이터가 모두 메모리에 저장되어 있어야 함.하지만 레지스터 용량은 극히 제한되어있기에, CPU는 반드시 빈번히 메모리에 접근하여 명령어의 데이터를 가져와야 함.또 명령어 실행 결과도 메모리에 다시 기록해야 함.CPU와 메모리 속도가 서로 잘 맞는지 확인해야 함.CPU와 메모리의 속도 차이시스템 성능의 속도가 상대적으로 느린 쪽에 맞추어 제한됨.CPU와 메모리의 속도가 같아야 가장 좋은 성능을 발휘할 수 있는 나무통 원리(cannikn law)를 만족함.하지만, CPU와 메모리는 시간이 지날 수록 속도 차이가 남.속도가 미친듯이 빠른 CPU..
함수 호출과 실행 시간 스택함수를 호출할 때, CPU가 호출된 함수의 첫 번째 기계 명령어로 점프한 이후 함수 실행이 완료되면 다시 원래 위치로 점프해야 함.함수 상태의 보존과 복원을 포함해야함.보존해야하는 상태 정보에는 반환 주소 뿐만 아니라 사용한 레지스터 정보도 포함됨.함수 A가 함수 B를 호출할 때 실행 정보는 함수 A 스택프레임에 저장됨.함수 B가 실행 완료되면 스택 프레임 정보를 기반으로 함수 A의 실행이 재개됨.시스템 호출과 커널 상태 스택디스크 파일을 읽고 쓰거나 새로운 스레드 생성할 때, 누가 파일을 읽고 쓰는 작업을 하는가? 누가 스레드를 생성하는가?운영체제ex) open 함수 호출 → 운영 체제가 파일을 여는 작업을 진행함.응용 프로그램은 시스템 호출을 통해 운영 체제에 서비스를 요청..
컴퓨터 시스템에는 함수 호출, 시스템 호출, 프로세스 전환, 스레드 전환, 인터럽트 처리와 같은 구조들이 있음.함수 호출을 통해 프로그래머는 코드 재사용성을 개선할 수 있음.시스템 호출로 프로그래머는 운영체제에 요청을 보낼 수 있음.프로세스와 스레드 전환으로 다중 작업이 가능함인터럽트 처리로 운영 체제가 외부 장치를 관리하게 할 수 있음.이러한 구조는 컴퓨터 시스템의 기반이 됨.레지스터레지스터를 사용하는 이유는 바로 속도 때문임.CPU가 메모리에 접근하는 속도는 레지스터에 접근하는 속도의 대략 100분의 1정도임.사실 레지스터와 메모리는 본질적 차이가 없음. 둘 다 정보를 저장하는데 사용함.단지 레지스터의 읽기 쓰기 속도가 훨씬 빠르고 제조 비용도 훨씬 비싸기에 용량에 한계가 있을 뿐임.스택 포인터 (스..
프로그래머는 모두 인터페이스 개념을 알고 있음.CPU 에 있어 인터페이스란?명령어 집합을 의미함.인터페이스에 해당하는 명령어 집합은 변경할 수 없지만 CPU 내부 구현, 즉 명령어 실행 방식은 변경이 가능함.이를 이해한 천재적인 엔지니어는 마이크로 명령어 개념을 제시함. 이길 수 없다면 함께하라: RISC와 동일한 CISC축소 명령어 집합의 주요 장점은 파이프라인 기술을 잘 활용할 수 있다는 것이었음.반면 복잡 명령어 집합은 명령어 실행 시간이 고르지 않아 파이프라인을 활용할 수 없었음.간단히 생각하면 복잡 명령어 집합이 축소 명령어 집합에 가깝게 변하면 문제가 해결됨.바로, 복잡 명령어 집합의 명령어를 CPU 내부에서 축소 명령어 집합의 간단한 명령어로 변환하는 것임.축소 명령어 집합의 간단한 명령어와..
시간이 흐르고 기술이 발전하면서 더이상 컴파일러와 저장 장치의 용량 제한 같은 객관적 조건의 제한을 받지 않음.메모리 용량 대비 가격이 급격히 떨어지기 시작함.컴파일러 기술이 발전해 프로그래머도 점점 고급 언어로 프로그램을 작성하기 시작함.복잡함을 단순함으로컴퓨터 과학자 데이비드 패터슨은 다음과 같이 말함.복잡 명령어 집합에서 성능을 향상 시키는 것으로 여겨지는 명령어는 실제로 CPU 내부 마이크로코드에 의해 가로막힘.오히려 마이크로코드를 제거하면 프로그램이 더 빠르게 실행되며, CPU를 구성하는 트랜지스터를 절약할 수 있음.마이크로코드 설계 아이디어는 복잡한 기계 명령어를 CPU 내부에서 비교적 간단한 기계 명령어로 변환하는 것임.컴파일러는 이 프로세스를 알지 못함.마이크로코드에 버그가 있으면 컴파일러..
기술을 논의할 때 그 진화 과정을 이해하지 못하고 현재에만 집중한다면 절대 그 기술을 이해할 수 없을 것임. 프로그래머의 눈에 보이는 CPU어떤 복잡한 대규모 응용 프로그램이든 간에 결국 컴파일러로 하나하나 간단한 기계 명령어로 변환함.본질적으로 CPU 입장에서 프로그램에 따른 차이가 없음.단지 명령어가 많은지 적은지의 차이만 있을 뿐임.CPU는 단순하게 실행파일에 적힌 명령어가 메모리에 적재되면 그걸 읽어 실행하기만 함. CPU의 능력 범위: 명령어 집합CPU 유형에 따라 고유한 능력 범위를 가지고 있음.이를 명령어 집합(instruction set architecture) 라고 함.명령어 집합에는 여러 가지 명령어가 포함됨.명령어 집합은 프로그래머가 프로그래밍에 사용함.서로 다른 형태의 CPU는 다른..
레시피와 코드, 볶음 요리와 스레드요리사는 레시피에 따라 특정 작업을 실행하여 특정한 요리를 만듦.ex) 레시피에 따라 돼지고기를 볶으면 돼지 두루치기 스레드가 됨.CPU는 기계 명령어에 따라 프로세스와 스레드를 실행함.운영체제 입장에서, CPU가 사용자 상태에서 실행하는 명령어는 모두 특정 스레드에 속해있음.요리사 수는 CPU 코어 수에 비유할 수 있음.일정 시간 동안 볶을 수 있는 요리 수는 스레드 수에 비유할 수 있음.‘요리사 수’가 ‘동시에 얼마나 많은 요리를 할 수 있는지’ 여부와 관련이 없음.CPU 코어 수와 스레드 수 사이에는 어떤 필연 관계도 없음.CPU는 하드웨어, 스레드는 소프트웨어 개념(실행 흐름이자 작업)임.즉, 단일 코어 시스템에서도 많은 스레드를 생성할 수 있음. (메모리가 충분..
const unsigned arraySize = 10000;int data[arraySize];long long sum = 0;for (unsigned i = 0; i = 128) { sum += data[c]; } }}만약 배열요소가 정렬된 상태라면 약 2.8초 만에 실행이 완료되지만, 배열 요소가 임의로 배치되면 실행 시간이 무려 약 7.5초에 달함.리눅스의 perf 도구를 이용하여 프로그램 실행 상태에 대한 초기 단계를 분석해서 문제를 확인해 볼 수 있음.perf 를 이용하면 CPU와 관련된 모든 중요한 정보를 확인할 수 있음.branch-misses 항목이 있는데, 정렬된 배열을 이용한 프로그램에서 예측 실패율은 0.02%에 불과하지만, 정렬되지 않은 배열을 이용한 프로그램에서 최고 14...