CPU

컴퓨터 시스템을 구성하는 요소는 다양하며, 각각의 구성요소들이 상호 작용을 통해서 전체 시스템이 동작하게 된다.

그 중 중앙 처리 장치(CPU, Central Processing Unit)는 컴퓨터 시스템에서 가장 중요한 부품 중 하나이다.

 

구성요소

연산 유닛(Arithmetic Logic Unit, ALU)

산술 및 논리 연산을 수행한다. 덧셈, 뺄셈, 곱셈, 나눗셈 같은 산술 연산과 AND, OR, NOT, XOR과 같은 논리 연산을 처리한다.

 

제어 유닛(Control Unit, CU)

메모리에서 명령어를 가져와 해독하고 실행한다. 또한 다른 구성요소들을 제어하여 명령어 실행에 필요한 데이터를 제공하거나 결과를 저장한다.

 

레지스터(Register)

CPU 내부의 작은 기억장치이다. 매우 빠른 접근 속도를 가지고 연산에 필요한 데이터를 저장하거나 중간 결과를 저장하는데 사용된다. 종류는 크게 범용, 프로그램 카운터, 명령, 주소 레지스터 등이 있다.

 

캐시 메모리(Cache Memory)

캐시 메모리는 CPU와 주 기억장치 사이에 위치하며 자주 사용되는 데이터와 명령어를 빠르게 접근할 수 있도록 저장한다. 캐시 메모리는 CPU 성능을 향상시키는 데 중요한 역할을 한다.

 

명령어 주기

CPU는 명령어 주기를 통해 작동한다.

1. 인출(Fetch) : 메모리에서 명령어를 가져오는 단계

2. 해독(Decode) : 가져온 명령어를 해독하여 실행할 동작을 결정하는 단계

3. 실행(Execute) :  해독된 명령어를 실행하는 단계

4. 저장(Store) :  실행 결과를 레지스터나 메모리에 저장하는 단계

 

성능

CPU의 성능은 클럭 속도, 코어 수, 캐시 크기, 명령어 집합 구조(ISA) 등 다양한 요소에 의해 영향을 받는다. 클럭 속도는 CPU가 초당 처리할 수 있는 명령어의 수를 나타내며, 코어 수는 동시에 처리할 수 있는 명령어 스트림의 수를 의미한다. 캐시 크기는 CPU와 메모리 사이에 위치한 고속 메모리의 용량을 나타내며, 명령어 집합 구조는 CPU가 어떤 종류의 명령어를 처리할 수 있는지를 결정한다.

 

다중 코어 프로세서와 파이프라이닝, 병렬 처리 등의 기술을 통해 성능을 향상시킬 수 있으며 이러한 기술은 동시에 여러 작업을 처리하거나 여러 단계로 구성된 작업을 동시에 진행함으로써 전체 시스템의 처리 속도를 높일 수 있다.

728x90
반응형

'Computer > Engineering' 카테고리의 다른 글

데이터 경로와 제어 유닛  (0) 2023.03.17
메모리  (0) 2023.03.17
명령 사이클과 명령어 집합 구조  (0) 2023.03.17
레지스터  (0) 2023.03.17
튜링 머신 : 컴퓨터 과학의 기초  (0) 2023.01.07

Visual Studio 2022

 

class 생성

멤버변수 int 하나

public class Test
{
	int data_1;
}

public static void Main(string[] args)
{
	Test test = new Test();
}

C# Class Size Test (Field int 1)

int 하나인데 크기가 24 바이트이다.

int = 4byte 인데 왜 6배나 되는걸까?

=>6개 이상일 때 크기 확인 해보기로함

public class Test
{
	public int data_1;
	public int data_2;
	public int data_3;
	public int data_4;
	public int data_5;
	public int data_6;
}

일단 int 6개로 테스트, 기대 결과는 그대로 24byte

C# Class Size Test (Field int 6)

이게 무슨일이지, 40 byte 가 나옴

처음 결과를 기준으로 생각해보면 24 + 16 즉 16 byre가 추가됨.

4(int) * 4(count) 라고 생각해보고 다시 필드를 int * 3으로 테스트

 

public class Test
{
    public int data_1;
    public int data_2;
    //public int data_3;
    //public int data_4;
    //public int data_5;
    //public int data_6;
}

예상한대로면 처음 결과인 24가 나와야함

C# Class Size Test (Field int 2)

결과는 기대한대로 나왔지만 여전히 24라는 크기가 이해가 안감,

혹시나해서 클래스를 인스턴스화 안했을때 한번 확인해봤지만 당연하게 해당 메모리 안잡힘

 

이번엔 하나씩 필드 늘려가면서 확인해보기로함

C# Class Size Test (Field int 3)

int * 4 일때는 동일하게 32

C# Class Size Test (Field int 5)

int * 5 부터 40 으로 잡혔음

 

그럼 그냥 빈 클래스는 얼마로 잡히나 확인했는데

애초에 비어있는 클래스를 인스턴스하면 24 byte 할당됨

여기서 2개씩 int 추가될 때마다 8 byte가 늘어나는데 이 늘어나는 값은 4(int) * 2(count) 맞음

 

비어있는 클래스가 왜 24 byte의 힙을 차지하는지 파악해보면될듯함

일단 Program 외부에 Test_2 클래스, 내부에는 Test_1 선언 후 비교

public class Test_2 { }
public class Program
{
    public class Test_1 { }
    public static void Main(string[] args)
    {
        Test_1 test_1 = new Test_1();
        Test_2 test_2 = new Test_2();
    }
}

C# Class Size Test_1 / Test_2 (empty)

테스트 해본 결과 클래스를 할당하면 기본 크기가 24로 잡히고 이 안에 8byte 까지는 포함시킬 수 있는걸로 보인다.

즉 기본 24 = 16(사용됨) + 8(여유 공간) 이고 크기가 24 byte를 넘을 경우 8byte 단위로 확장되는걸로 파악됨

 

구글링 해본 결과 내가 원하는 정보를 찾을 수 있었다.

 

OF MEMORY AND STRING_Jon Sket

 

본래 글의 취지는 .Net에서 ASCII 문자열의 효율적인 표현에 관한것에 대한 답이다.

위 글에서는 x86과 x64를 모두 비교하고 있는데 이 글에서는 x64를 기준으로 정리한다.

 

그럼 이제 왜 0byte는 될수없는지 그리고 24byte 중 사용할 수 없는 16byte와 사용 가능한 8byte는 무엇 때문인지 정리한다.

 

우선 C#에서 모든 타입은 object 타입을 베이스로한다. 그리고 이 object 타입의 크기는 24byte이다.

이 24byte의 크기는 16byte의 오버헤드와 참조를 위한 8byte로 이루어진다. 

 

오버헤드란 처리를 하기 위해 들어가는 간접적인 처리 시간, 메모리 등을 말한다. 즉 C#의 object를 메모리에 유지시키는데 필요한 메모리 양이 16byte이며 .Net의 CLR은 데이터가 없는 object에서 작업할 수 없기 때문에 오버헤드만 가지고는 object를 사용할 수 없고 여유 공간이 필요하며 이 크기가 8byte이다. 따라서 선언될 수 있는 가장 작은 크기의 메모리는 24byte가 된다.

 

이 중 여유공간인 8byte는 실제 데이터를 저장할 수 있기 때문에 int가 2개 포함된 class역시 24byte였다. 이 8byte는 전체를 사용할 수 있는 공간이기 때문에 1byte로 8를 사용하는것도 가능하다. 그리고 int가 3개가 될때 24byte에서 8byte로 증가했는데 이것은 메모리의 경계인 패딩의 크기가 8byte였기 때문이다. 

 

class 역시 object 타입을 베이스로 하고 있고 빈 class를 인스턴스화 하는것은 object를 생성하는것과 마찬가지이기 때문에 빈 class가 24byte라는것도 이제 납득이 간다. 

 

오버헤드에 대한 내용

overhead - Andrew Hunter
overhead - Stack Overflow

 

왜 이렇게 많은 공간이 필요한지 또 이 공간은 어떤식으로 사용되는지 궁금한데 이 부분은 더 자세히 찾아봐야 될것같다.

 

정리

64bit 기준으로 

1. 비어있는 class 또한 하나의 object이다. 따라서 24byte 메모리를 차지한다.

2. 이 메모리는 16byte의 내부 데이터 참조형으로 사용되는 오버헤드와 8byte의 여유공간으로 구성된다.

3. 여유공간은 모두 사용이 가능하며 메모리는 8byte의 패딩을 가지고 있다.

 

728x90
반응형

'Memo' 카테고리의 다른 글

다국어를 제공하는 방법에 대해서  (0) 2023.05.10

Interoperability(Interop)

상호운용성

unmanaged code에 대한 기존 투자를 보존하고 활용할 수 있게 한다.

즉 CLR을 사용하지 않는 어셈블리를 CLR에서 사용할 수 있게 만드는 것이다.

interop은 managed와 unmanaged를 오고가는 메모리 비용과 코드 작성 비용 때문에 최소화하는게 좋다.

 

COM Interop

Component Object Model(COM) 을 사용하면 개체의 기능을 다른 컴포넌트와 윈도우 플랫폼의 호스트 프로그램에 사용할 수 있다. 사용자가 기존 코드 베이스와 상호 운용할 수 있도록 .Net 프레임워크에서 COM라이브러리를 통해 interop을 지원한다.

 

Platform Invoke(P/Invoke)

P/Invoke는 사용자의 managed code에서 unmanaged 라이브러리의 구조, 콜백 그리고 기능에 접근할 수 있도록 한다. 대부분 P/Invoke API는 SystemSystem.Runtime.InteropServices 두 개의 네임스페이스를 포함한다.

이 두개의 네임스페이스를 사용하면 네이티브 컴포넌트를 사용할 수 있는 도구가 제공된다.

using System;
using System.Runtime.InteropServices;

public class Program
{
	// Import dll (containing the funtion)
    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)
    // Define
    private static extern int MessageBox(IntPtr hWnd, string IpText, string IpCaption, uint uType);
    
    public static void Main(string[] args)
    {
    	// Invoke the function as a regular managed method
        MessageBox(IntPtr.Zero, "Command-line message box", "Attention!", 0);
    }
}
  1. Attribute
    • [DllImport] attribute은 런타임에 unmanaged DLL을 로드할것을 알린다.
    • "user32.dll" 문자열은 사용할 기능이 포함된 DLL을 대상으로 한다.
    • CharSet = CharSet.Unicode 문자열을 Mashalling하는데 사용할 문자 집합을 지정한다.
    • SetLastError = true 런타임에서 오류가 발생했을때 사용자가 Mashal.GetLastWin32Error()를 통해서 에러코드를 감지할 수 있게한다.
  2. Declare
    • 메서드 선언시 메서드명은 사용할 unmanaged code와 동일한 이름으로 작성한다.
    • 이때 extern 키워드를 통해서 해당 메서드가 외부의 메서드임을 런타임에 알린다.
    • 런타임은 외부 메서드라는것을 알게되면 해당 managed 메서드를 호출할 때 attribute의 설정을 통해 특정된 DLL을 찾아서 실행시킨다.
  3. Main method
    • managed code 즉 현재 작업중인 코드에서 extern으로 선언한 메서드를 호출하여 외부 메서드를 사용한다. 

 

Managed C++(C++/CLI)

Managed Extensions for C++ 또는 Managed C++은 문법적 그리고 구문적 확장, 키워드와 속성을 포함하고 C++의 구문 및 언어를 가져오는 .Net Framework의 C++ 언어 확장 집합이다. 이 확장자는 managed code상에서 C++ 코드가 CLR의 대상이 될 수 있도록 그리고 지속적으로 native code와 상호 운용될 수 있게하려고 마이크로소프트에서 만들었다.

 

2004년 Managed C++은 구문을 명확하고 단순화하고 managed generics을 포함하도록 기능을 크게 개선시켰다. 이렇게 새로운 확장자는 C++/CLI로 지정되었고 Visual Studio 2005 이후에 포함되면서 Managed C++을 대체하였다.

 

SWIG

Simplefied Wrapper and Interface Generator

C 또는 C++로 작성된 컴퓨터 프로그램이나 라이브러리 다른 프로그래밍 언어에서 사용할 수 있도록 연결하는데 사용하는 오픈소스 도구이다. 

주목적은 네이티브 함수의 호출, 복잡한 자료형을 함수에 전달, 메모리 부적절하게 해제하지 못하게 방지, 언어 간에 오브젝트 클래스를 상속할 수 있게 하는것이다.

728x90
반응형

+ Recent posts