<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>gb_leem.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sat, 03 Aug 2024 16:36:56 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>gb_leem.log</title>
            <url>https://velog.velcdn.com/images/gb_leem/profile/4526ed57-2871-41fb-87ed-2aed6a58305e/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. gb_leem.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/gb_leem" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[유니티 github language 비율 문제 해결]]></title>
            <link>https://velog.io/@gb_leem/%EC%9C%A0%EB%8B%88%ED%8B%B0-github-language-%EB%B9%84%EC%9C%A8-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@gb_leem/%EC%9C%A0%EB%8B%88%ED%8B%B0-github-language-%EB%B9%84%EC%9C%A8-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Sat, 03 Aug 2024 16:36:56 GMT</pubDate>
            <description><![CDATA[<ul>
<li>유니티 프로젝트를 깃허브에 올려 관리하는데, languages 비율에 ShaderLab이라는 것의 비율이 계속 표시되는 문제가 있었다.</li>
<li>찾아보니 TextMeshPro 때문에 발생하는 문제였다. 이것을 해결하기 위해 먼저 gitignore에 <code>TextMesh Pro/</code> 추가했지만, 바로 적용이 되지 않았다.</li>
<li>해결책으로 cache를 지워야 한다고 해서 해당 내용을 정리해 보았다.<h4 id="1-gitignore-수정">1. gitignore 수정</h4>
</li>
<li>gitignore에 <code>TextMesh Pro/</code> 추가<h4 id="2-cmd-창으로-cache-제거">2. cmd 창으로 cache 제거</h4>
</li>
<li>깃으로 관리되는 폴더 안으로 들어가서 <code>git rm -r --cached .</code> 명령어 입력
<img src="https://velog.velcdn.com/images/gb_leem/post/a2bfb5a3-2607-478b-b046-631c7a8daa86/image.PNG" alt=""></li>
<li><code>git add .</code> 명령어 입력
<img src="https://velog.velcdn.com/images/gb_leem/post/000e608b-f18f-4e31-8dcc-99304fcb199c/image.PNG" alt=""></li>
<li><code>git commit -m &quot;커밋 내용&quot;</code> 
<img src="https://velog.velcdn.com/images/gb_leem/post/706fd6f1-0361-4229-bdd1-b0736e045649/image.PNG" alt=""></li>
<li>커밋을 하면 아래와 같이 지워진 것을 볼 수 있다.
<img src="https://velog.velcdn.com/images/gb_leem/post/674c1e0b-4d1c-4177-97bd-1a03a580ee94/image.PNG" alt=""></li>
<li>마지막으로 <code>git push</code>를 통해 마무리
<img src="https://velog.velcdn.com/images/gb_leem/post/f47aef97-13f2-462b-abe3-1b45c5e803f9/image.PNG" alt=""></li>
<li>제대로 변경된 모습을 볼 수 있다.
<img src="https://velog.velcdn.com/images/gb_leem/post/2b6a7bb2-4b89-4621-8ae9-113034d851a5/image.PNG" alt=""></li>
</ul>
<h4 id="참고">참고</h4>
<p><a href="https://adjh54.tistory.com/376#google_vignette">https://adjh54.tistory.com/376#google_vignette</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[map vs hash map]]></title>
            <link>https://velog.io/@gb_leem/map-vs-hash-map</link>
            <guid>https://velog.io/@gb_leem/map-vs-hash-map</guid>
            <pubDate>Thu, 04 Jul 2024 17:43:19 GMT</pubDate>
            <description><![CDATA[<h2 id="map">map</h2>
<ul>
<li>red black tree (이진 균형 트리) 구조</li>
<li>추가/탐색/삭제 : O(logN)</li>
<li>코드 <pre><code>#include &lt;map&gt;
using namespace std;
</code></pre></li>
</ul>
<p>int main()
{
    map&lt;int, string&gt; m;
    m.insert({100, &quot;Kim&quot;});
    m.insert({200, &quot;Jun&quot;});
    m.insert({100, &quot;Lee&quot;});</p>
<pre><code>//중복된 값을 쓰고 싶으면, multimap 써야함
cout &lt;&lt; m[100] &lt;&lt;&quot; \n&quot;; //Kim
m[100] = &quot;Leem&quot;; //value값 덮어쓴다.
cout &lt;&lt; m[100] &lt;&lt; &quot;\n&quot;; //Leem</code></pre><p>}</p>
<pre><code>
## hash map
* C++ STL에서 unordered_map
* C#에서는 dictionary
* 추가/탐색/삭제 : O(1)
  * 메모리를 더 많이 쓰는 대신 속도가 빠르다.
* 코드 
`unorderd_map&lt;key, value&gt;`
`unordered_multimap&lt;key, value&gt;`
  * unordered_multimap에서는 `[]` operator 사용 불가능
  * `insert` 로 값 넣기
* unordered_map을 순회해서 값을 찾고 싶을때</code></pre><p>auto u = um.equal_range(cur);
for(auto it = u.first; it != u.second; ++it)
{
    cout&lt;<it->second&lt;&lt;&quot;\n&quot;;
}</p>
<pre><code>### cf) hash table
* table
  * O(1)에 추가/탐색/삭제를 할 수 있는 구조
  * 키와 데이터의 쌍으로 구성
  * 그러나 데이터가 너무 커지면, 더이상 효율성이 사라짐
  * 이 문제를 해결하기 위해 hash 사용
* hash
  * 키에 따라 데이터를 넣을 때 충돌된 것을 해결해주는 방법
  * 충돌 방지 기법
    * 선형 조사법
      * 이미 있는 key 값이라면, 한칸 뒤로 밀면서 빈 key값 찾기
    * 이차 조사법
      * 이미 있는 key 값이라면, 제곱값 만큼 밀면서 빈 key값 찾기
    * 체이닝 기법
      * 이미 있는 key 값이라면, 중복된 key값을 가지는 value 넣어주기
* hash 예시 코드</code></pre><p>void TestHash()
{
    struct User
    {
        int userId = 0;
        string username;
    };</p>
<pre><code>vector&lt;User&gt; users;
users.resize(1000);

const int userId = 123456789;
int key = (userId % 1000); //hash 함수를 통해 만든 key

//정보 넣기
users[key] = User{ userId, &quot;Leem&quot; };

//정보 찾기
User&amp; user = users[key];
if (user.userId == userId)
{
    string name = user.username;
    cout &lt;&lt; name &lt;&lt; &quot;\n&quot;;
}  </code></pre><p>}</p>
<pre><code>
* 체이닝 예시 코드</code></pre><p>void TestHashTableChaining()
{
    struct User
    {
        int userId = 0;
        string username;
    };</p>
<pre><code>vector&lt;vector&lt;User&gt;&gt; users;
users.resize(1000);

const int userId = 123456789;
int key = (userId % 1000); //hash 함수를 통해 만든 key

//정보 넣기
users[key].push_back(User{ userId, &quot;Leem&quot; });
users[key].push_back(User{ 789, &quot;Jun&quot; });


//정보 찾기
vector&lt;User&gt;&amp; bucket = users[key];
for (const auto&amp; user : bucket)
{
    if (user.userId == userId)
    {
        string name = user.username;
        cout &lt;&lt; name &lt;&lt; &quot;\n&quot;;
    }
}</code></pre><p>}</p>
<pre><code>### 참고) unordered_map에서 key값으로 pair를 쓰고 싶을 때</code></pre><p>struct pair_hash
{
    template&lt;class T1, class T2&gt;
    size_t operator () (const pair&lt;T1,T2&gt;&amp;pair) const
    {
        auto hash1 = hash<T1>{}(pair.first);
        auto hash2 = hash<T2>{}(pair.second);
        return hash1^hash2;<br>    }
}</p>
<p>unordered_map&lt;pair&lt;string, string&gt;, int, pair_hash&gt; um;
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 리뷰 6 - 메모리]]></title>
            <link>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-6-%EB%A9%94%EB%AA%A8%EB%A6%AC</link>
            <guid>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-6-%EB%A9%94%EB%AA%A8%EB%A6%AC</guid>
            <pubDate>Tue, 04 Jun 2024 20:05:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고 자료 : 혼자 공부하는 컴퓨터구조 + 운영체제
사진 출처 : Operating System Concepts 10E</p>
</blockquote>
<h2 id="1-연속-메모리-할당">1. 연속 메모리 할당</h2>
<h3 id="스와핑">&lt;스와핑&gt;</h3>
<h4 id="1-개요">1. 개요</h4>
<ul>
<li>현재 사용되지 않는 프로세스들을 <strong>보조기억장치의 일부 영역</strong>으로 쫓아내고 생긴 공간에 새 프로세스 적재</li>
<li>스왑 인, 스왑 아웃
<img src="https://velog.velcdn.com/images/gb_leem/post/f396b6c0-46f3-44c3-9d41-eca4d4c2a998/image.png" alt=""></li>
</ul>
<h4 id="2-스와핑의-이점">2. 스와핑의 이점</h4>
<ul>
<li>프로세스들이 요구하는 메모리 공간 크기 &gt; 실제 메모리 크기<h3 id="메모리-할당">&lt;메모리 할당&gt;</h3>
<h4 id="1-개요-1">1. 개요</h4>
</li>
<li>프로세스는 메모리의 빈 공간에 할당되어야 한다.</li>
<li>빈 공간이 여러 개라면, <strong>어느 곳에 할당하는 것이 이득일까?</strong><ul>
<li>세가지 방식을 이용: 최초, 최적, 최악 적합<h4 id="2-최초-적합-first-fit">2. 최초 적합 (first-fit)</h4>
</li>
</ul>
</li>
<li>os가 메모리 내의 빈 공간을 <strong>순서대로</strong> 검색하다가 적재할 수 있는 공간을 발견하면 그 공간에 배치하기</li>
<li>장점: 검색의 최소화 &amp; 빠른 할당<h4 id="3-최적-적합-best-fit">3. 최적 적합 (best-fit)</h4>
</li>
<li>os가 빈 공간을 <strong>모두 검색해본 다음</strong>, 적재 가능한 <strong>가장 작은</strong> 공간에 할당하기<h4 id="4-최악-적합-worst-fit">4. 최악 적합 (worst-fit)</h4>
</li>
<li>os가 빈 공간을 <strong>모두 검색해본 다음</strong>, 적재 가능한 <strong>가장 큰</strong> 공간에 할당<h3 id="외부-단편화-external-fragmentation">&lt;외부 단편화 (external fragmentation)&gt;</h3>
<h4 id="1-개요-2">1. 개요</h4>
</li>
<li>위에서 언급한 세가지 방식, 즉 <strong>프로세스를 연속적으로 할당</strong>하는 방식은 메모리를 효율적으로 사용하는 방법이 아니다.<h4 id="2-외부-단편화-예시">2. 외부 단편화 예시</h4>
</li>
<li>프로세스들이 실행되고 종료되길 반복하면서 메모리 사이사이 빈 공간이 발생하는데,</li>
<li>빈 공간의 합만큼의 메모리를 할당하지 못해서, <ul>
<li>빈 공간의 합은 50MB이지만, 30MB, 20MB 이런식으로 떨어져 있으므로 50MB짜리 프로세스를 할당하지 못함</li>
<li>아래 그림 참고</li>
</ul>
</li>
<li>메모리가 낭비되는 현상
<img src="https://velog.velcdn.com/images/gb_leem/post/7aab8558-909d-4b46-880c-5c2064fd11a0/image.png" alt=""><h3 id="외부-단편화-해결-방법">&lt;외부 단편화 해결 방법&gt;</h3>
<h4 id="1-메모리-압축-compaction">1. 메모리 압축 (Compaction)</h4>
</li>
<li>여기저기 흩어져 있는 빈 공간들을 하나로 모으는 방식</li>
<li>프로세스를 재배치시켜 작은 빈 공간들을 하나의 큰 빈 공간으로 만드는 방법</li>
<li>오버헤드가 크다는 단점</li>
<li>그렇다면 현재는 어떤 방식을 사용하는가?<h4 id="--2-가상-메모리-기법-페이징">-&gt; 2. 가상 메모리 기법, 페이징!</h4>
<h2 id="2-페이징을-통해-가상-메모리-관리">2. 페이징을 통해 가상 메모리 관리</h2>
<h3 id="연속-메모리-할당의-문제점">&lt;연속 메모리 할당의 문제점&gt;</h3>
<h4 id="1-외부-단편화">1. 외부 단편화</h4>
<h4 id="2-물리-메모리보다-큰-프로세스-실행-불가">2. 물리 메모리보다 큰 프로세스 실행 불가</h4>
<h3 id="가상-메모리-virtual-memory">&lt;가상 메모리 (virtual memory)&gt;</h3>
<h4 id="1-개요-3">1. 개요</h4>
</li>
<li><strong>가상 메모리란, 실행하고자 하는 프로그램을 일부만 메모리에 적재해서 물리 메모리보다 큰 프로세스를 실행하도록 하는 기술</strong></li>
<li>페이징과 세그멘테이션이 존재<h3 id="페이징-paging">&lt;페이징 (paging)&gt;</h3>
<h4 id="1-개요-4">1. 개요</h4>
</li>
<li>외부 단편화의 근본적인 문제는, 각기 <strong>다른 크기의</strong> 프로세스를 메모리에 연속적으로 할당했기 때문임</li>
<li>모든 프로세스가 같은 크기였다면, 외부 단편화 발생 x</li>
<li>이러한 아이디어를 사용한 것이 페이징<h4 id="2-페이징">2. 페이징</h4>
</li>
<li>간단하게 말하면 프로세스를 일정 크기로 자르고, 이를 메모리에 불연속적으로 할당하도록 하는 기술</li>
<li>페이징 동작 방식<ul>
<li>프로세스의 논리 주소 공간을 페이지(page)라는 일정 단위로 자르고,</li>
<li>메모리의 물리 주소 공간을 프레임(frame)이라는 페이지와 동일한 일정한 단위로 자른 뒤</li>
<li>페이지를 프레임에 할당하는 가상 메모리 관리 기법</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/0f4cb989-1495-40be-a4be-6fd9a0ad0de2/image.png" alt=""></p>
<h4 id="3-페이징에서의-스와핑">3. 페이징에서의 스와핑</h4>
<ul>
<li>프로세스 단위의 스왑 인, 아웃이 아닌 페이지 단위의 페이지 인, 아웃 실행<ul>
<li>메모리에 적재될 필요가 없는 페이지들은 보조기억장치로 스왑 아웃 (페이지 아웃)</li>
<li>실행에 필요한 페이지들은 메모리로 스왑 인(페이지 인)</li>
</ul>
</li>
<li>프로세스를 실행하기 위해 모든 페이지가 적재될 필요 없다.<ul>
<li>물리 메모리보다 큰 프로세스 실행 가능!<h4 id="4-페이징에서의-의문점">4. 페이징에서의 의문점</h4>
</li>
</ul>
</li>
<li>프로세스를 이루른 페이지가 어느 프레임에 적재되어 있는지 CPU가 일일이 알기는 어렵다.</li>
<li>프로세스가 메모리에 불연속적으로 배치되어있다면, CPU 입장에서 이를 순차적으로 실행할 수 없다.</li>
<li>CPU 입장에서 다음에 실행할 명령어 위치를 찾기 어려움</li>
<li><strong>그렇다면, 물리 메모리에 분리되어 저장된 것을 어떻게 다시 모아서 CPU가 실행할 것인가? -&gt; 페이지 테이블 이용!!</strong><h3 id="페이지-테이블">&lt;페이지 테이블&gt;</h3>
<h4 id="1-개요-5">1. 개요</h4>
</li>
<li>실제 메모리 내의 주소인 <strong>물리 주소에 불연속적</strong>으로 배치되더라도</li>
<li>CPU가 바라보는 주소인 <strong>논리 주소에는 연속적</strong>으로 배치되도록 하는 방법<h4 id="2-페이지-테이블">2. 페이지 테이블</h4>
</li>
<li><strong>페이지 번호와 프레임 번호를 짝지어 주는 일종의 이정표</strong></li>
<li>물리적으로는 분산되어 저장되어 있더라도 CPU입장에서 바라본 논리 주소는 <strong>연속적이다</strong></li>
<li>결과적으로 CPU는 논리 주소를 순차적으로 실행하면 된다.</li>
<li>그러나 내부 단편화라는 문제 발생..<h3 id="내부-단편화-internal-fragmentation">&lt;내부 단편화 (internal fragmentation)&gt;</h3>
<h4 id="1-개요-6">1. 개요</h4>
</li>
<li>내부 단편화는 어떤 프로세스의 크기가 페이지 크기의 배수가 되지 않을 때 발생 </li>
<li>결과적으로 하나의 페이지 크기보다 작은 크기가 낭비된다.</li>
<li>낭비되는 크기가 외부 단편화 보다는 작다. (대체로)<h3 id="프로세스-테이블-베이스-레지스터-ptbr">&lt;프로세스 테이블 베이스 레지스터 (PTBR)&gt;</h3>
<h4 id="1-개요-7">1. 개요</h4>
</li>
<li>PTBR은 각 프로세스가 가지고 있는 페이지 테이블이 어디에 저장되어있는지를 나타내기 위한 레지스터<ul>
<li>각 페이지 테이블은 CPU 내의 PTBR이 가리킨다.
<img src="https://velog.velcdn.com/images/gb_leem/post/1f407692-f358-479f-84ec-9f0f544d41b5/image.png" alt=""><h4 id="2-문제점">2. 문제점</h4>
</li>
</ul>
</li>
<li><strong>페이지 테이블이 메모리에 있다면, 메모리 접근 시간이 2배로 든다.</strong><ul>
<li>페이지 테이블을 참조할 때 + 페이지를 참조할 때</li>
</ul>
</li>
<li>해결방안은 TLB를 사용하기!!<h3 id="tlb">&lt; TLB&gt;</h3>
<h4 id="1-개요-8">1. 개요</h4>
</li>
<li>TLB란 페이지 테이블의 일부를 가져와서 저장하는 캐시 메모리</li>
<li>자주 참고하는 페이지 테이블 내용을 저장한다.<h4 id="2-동작-방식">2. 동작 방식</h4>
</li>
<li><strong>TLB hit</strong><ul>
<li>CPU가 접근하려는 논리 주소가 TLB에 있는 경우</li>
<li>메모리 접근을 한번만에 수행가능</li>
</ul>
</li>
<li><strong>TLB miss</strong><ul>
<li>CPU가 접근하려는 논리 주소가 TLB에 없는 경우</li>
<li>메모리 접근을 두번할 수 밖에 없다.<h3 id="페이징에서의-주소-변환">&lt;페이징에서의 주소 변환&gt;</h3>
<h4 id="1-개요-9">1. 개요</h4>
</li>
</ul>
</li>
<li>특정 주소에 접근하기 위해 필요한 정보<ul>
<li>어떤 페이지, 프레임에 접근하고 싶은지</li>
<li>접근하고자하는 주소가 그 페이지,프레임으로부터 얼마나 떨어져 있는지<h4 id="2-페이징-시스템에서의-논리-주소의-구조">2. 페이징 시스템에서의 논리 주소의 구조</h4>
</li>
</ul>
</li>
<li>페이지 번호와 변위를 가짐</li>
<li>&lt;페이지, 변위&gt; 로 이루어진 논리 주소는, 페이지 테이블을 통해 &lt;프레임 번호, 변위&gt;인 물리 주소로 변환된다.<ul>
<li>이때 변위는 같아야 한다.
<img src="https://velog.velcdn.com/images/gb_leem/post/1fdb145f-a583-40aa-8b05-bba5b34722f3/image.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="페이지-테이블-엔트리">&lt;페이지 테이블 엔트리&gt;</h3>
<h4 id="1-개요-10">1. 개요</h4>
<ul>
<li>페이지 테이블의 각각의 행을 페이지 테이블 엔트리(PTE)라고 한다.<h4 id="2-pte에-담기는-정보">2. PTE에 담기는 정보</h4>
</li>
<li><strong>페이지 번호</strong></li>
<li><strong>프레임 정보</strong></li>
<li><strong>유효 비트</strong><ul>
<li>현재 해당 페이지에 <strong>접근 가능한지 여부</strong>를 알려줌<ul>
<li>유효 비트가 1이면 메모리에 적재된 페이지, 0이면 적재되지 않은 페이지</li>
<li>유효 비트가 0인 페이지에 접근하려 하면, <strong>page fault</strong>라는 인터럽트 발생</li>
<li><blockquote>
<p>CPU가 기존 작업 내용 백업</p>
</blockquote>
</li>
<li><blockquote>
<p>페이지 폴트 처리 루틴 실행</p>
</blockquote>
</li>
<li><blockquote>
<p>페이지 처리 루틴은 원하는 페이지 메모리로 가져온 뒤 유효 비트를 1로 변경</p>
</blockquote>
</li>
<li><blockquote>
<p>페이지 폴트를 처리했다면, CPU는 해당 페이지에 접근 가능</p>
</blockquote>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>보호 비트</strong><ul>
<li>예를 들어 읽기 전용 페이지같은 경우, 보호 비트를 1로 설정해서 쓰기와 같은 다른 작업을 못하게 한다.</li>
</ul>
</li>
<li><strong>참조 비트</strong><ul>
<li>CPU가 해당 페이지에 접근한 적이 있다면 1, 없다면 0</li>
</ul>
</li>
<li><strong>수정 비트 (dirty bit)</strong><ul>
<li>CPU가 이 페이지에 데이터를 쓴 적이 있는지 여부</li>
<li>swaping을 위해서 존재</li>
<li>만약 페이지가 수정된다면, 보조기억장치에도 쓰기 작업을 해야함</li>
</ul>
</li>
</ul>
<h3 id="쓰기-시-복사-copy-on-write">&lt;쓰기 시 복사 (Copy on Write)&gt;</h3>
<h4 id="1-개요-11">1. 개요</h4>
<ul>
<li>프로세스를 fork()하면 부모와 같은 내용을 가진 자식 프로세스가 생기므로,</li>
<li>프로세스 생성 시간이 지연되고, 메모리가 낭비되는 단점이 있다.</li>
</ul>
<h4 id="2-쓰기-시-복사">2. 쓰기 시 복사</h4>
<ul>
<li>fork된 자식 프로세스는 부모 프로세스와 동일한 프레임을 가리키는 것<ul>
<li>만약 이때 아무 쓰기 작업도 이루어지지 않으면, 현재 상태를 유지한다.</li>
</ul>
</li>
<li>그러나 쓰기 작업을 하게 된다면,<ul>
<li>쓰기 작업을 한 페이지는 별도의 공간으로 복제된다.</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/2fb3bed8-bc9c-4516-9d8a-b70bbdf1636e/image.png" alt=""></p>
<h3 id="계층적-페이징">&lt;계층적 페이징&gt;</h3>
<h4 id="1-개요-12">1. 개요</h4>
<ul>
<li>프로세스 테이블의 크기는 생각보다 작지 않기에, 프로세스를 이루는 모든 PTE에 메모리에 두는 것은 낭비이다.</li>
<li>프로세스를 이루는 모든 PTE를 항상 메모리에 유지하지 않는 기법<h4 id="2-계층적-페이징">2. 계층적 페이징</h4>
</li>
<li>페이지 테이블을 페이징하여, 여러 단계의 페이지를 두는 방식</li>
<li>CPU와 가장 가까이 위치한 페이지 테이블 (outer page table)만 항상 메모리에 유지</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/5ff1c339-27a9-42c0-bb9d-fbc1f206dfa8/image.PNG" alt=""></p>
<h2 id="3-페이지-교체와-프레임-할당">3. 페이지 교체와 프레임 할당</h2>
<ul>
<li>물리 메모리보다 큰 프로세스를 실행할 수 있지만, 물리 메모리의 크기는 한정되어있다.</li>
<li>결과적으로<ul>
<li>기존에 적재된 불필요한 페이지를 선별하여 보조기억장치로 내보내고, (<strong>페이지 교체</strong>)</li>
<li>프로세스들에게 적절한 수의 프레임을 할당해야 함! (<strong>프레임 할당</strong>)<h3 id="요구-페이징-demand-paging">&lt;요구 페이징 (demand paging)&gt;</h3>
<h4 id="1-개요-13">1. 개요</h4>
</li>
</ul>
</li>
<li>처음부터 모든 페이지를 적재하지 않고 필요한 페이지만 메모리에 적재하는 기법<h4 id="2-요구-페이징">2. 요구 페이징</h4>
1) CPU가 특정 페이지에 접근하는 명령어 실행
2) 해당 페이지가 현재 메모리에 있을 경우 (유효비트가 1인 경우) CPU는 페이지가 적재된 프레임에 접근한다.
3) 해당 페이지가 현재 메모리에 없을 경우 (유효비트가 0인 경우) 페이지 폴트 발생
4) 페이지 폴트 시에는 해당 페이지를 메모리로 적재하고 유효 비트를 1로 설정한다.
5) 다시 1번 수행<h4 id="cf-순수-요구-페이징">cf) 순수 요구 페이징</h4>
</li>
<li>아무런 페이지도 메모리에 적재하지 않고 실행하는 기법</li>
<li>첫번째 명령어를 실행하는 순간부터, 계속해서 페이지 폴트 발생</li>
<li>점차적으로 페이지 폴트가 적어진다<h4 id="3-요구-페이징이-해결해야-할-문제">3. 요구 페이징이 해결해야 할 문제</h4>
</li>
<li><strong>페이지 교체</strong></li>
<li><strong>프레임 할당</strong><h3 id="페이지-교체">&lt;페이지 교체&gt;</h3>
<h4 id="1-개요-14">1. 개요</h4>
</li>
<li>요구 페이징 기법으로 페이지를 적재하다보면 언젠가는 메모리가 가득 찬다.</li>
<li>당장 실행에 필요한 페이지를 적재하기 위해 적재된 페이지를 보조 기억장치로 내려야 하는데,</li>
<li><strong>이때 어떤 페이지를 내보내야 하는가?</strong></li>
</ul>
<h4 id="2-페이지-교체-알고리즘">2. 페이지 교체 알고리즘</h4>
<ul>
<li>좋은 페이지 알고리즘은?<ul>
<li><strong>페이지 폴트가 적은 알고리즘!</strong></li>
<li>페이지 폴트가 발생하는 순간 보조기억장치로 접근해야 하므로 성능이 저하되기 때문에</li>
</ul>
</li>
<li>페이지 폴트의 횟수를 알기 위해 <strong>페이지 참조열</strong> 이용</li>
</ul>
<h4 id="3-페이지-참조열-page-reference-string">3. 페이지 참조열 (page reference string)</h4>
<ul>
<li>CPU가 참조하는 페이지들 중 연속된 페이지를 생략한 페이지열</li>
<li>연속된 페이지를 삭제해야 페이지 폴트를 줄일 수 있다.<ul>
<li>ex)<ul>
<li>2 2 2 3 5 5 5 3 3 7 : 페이지 참조 순서</li>
<li>2 3 5 3 7 : 페이지 참조열<h3 id="페이지-교체-알고리즘">&lt;페이지 교체 알고리즘&gt;</h3>
<h4 id="1-fifo">1. FIFO</h4>
</li>
</ul>
</li>
</ul>
</li>
<li>가장 단순한 방식</li>
<li>메모리에 가장 먼저 올라온 페이지부터 내리는 방식</li>
<li>문제점<ul>
<li>프로그램 초기에 적재되었는데, 프로그램 실행 내내 사용될 페이지가 내쫓아진다면 성능면에서 이점이 없다.</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/ce9e6fbe-f09e-466a-8a44-f8f9e74e69d8/image.png" alt=""></p>
<h4 id="2-2차-기회second-chance-페이지-교체-알고리즘">2. 2차 기회(second-chance) 페이지 교체 알고리즘</h4>
<ul>
<li>FIFO의 단점을 보완한 알고리즘</li>
<li>동작 방식<ul>
<li>참조 비트1<ul>
<li>CPU가 한 번 참조한 적이 있는 페이지</li>
<li><blockquote>
<p>오래되긴 했지만, 자주 쓴 것</p>
</blockquote>
</li>
<li>한번 더 기회를 주기 </li>
<li><blockquote>
<p>참조 비트를 0으로 초기화 하고</p>
</blockquote>
</li>
<li><blockquote>
<p>적재 시간을 현재로 바꿈</p>
</blockquote>
</li>
</ul>
</li>
<li>참조 비트0<ul>
<li>CPU가 참조한 적이 없는 페이지</li>
<li>내쫓기<h4 id="3-최적optimal-페이지-교체-알고리즘">3. 최적(Optimal) 페이지 교체 알고리즘</h4>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>앞으로의 사용 빈도가 가장 낮은</strong> 페이지를 교체하는 알고리즘<ul>
<li>CPU에 의해 참조되는 횟수를 고려</li>
<li>메모리에 오래 남아야 할 페이지는 자주 사용될 페이지!</li>
</ul>
</li>
<li>동작 방식 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/cebacbdf-b651-415c-9fc8-5958558f2a08/image.png" alt=""></p>
<ul>
<li>문제점<ul>
<li>가장 낮은 페이지 폴트율을 보장하기는 하지만,</li>
<li>구현이 어렵다. (예측을 어떻게 할건데?)<h4 id="4-lru-least-recently-used-페이지-교체-알고리즘">4. LRU (Least-Recently-Used) 페이지 교체 알고리즘</h4>
</li>
</ul>
</li>
<li><strong>가장 오래 사용되지 않은</strong> 페이지 교체</li>
<li>동작 방식</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/208dff9b-d5aa-446a-9000-24815980a84c/image.png" alt=""></p>
<h3 id="스래싱">&lt;스래싱&gt;</h3>
<h4 id="1-개요-15">1. 개요</h4>
<ul>
<li>페이지 폴트가 자주 발생하는 이유<ul>
<li>좋지 않은 페이지 교체 알고리즘을 사용했기 때문</li>
<li>프로세스가 사용할 수 있는 프레임 자체가 적어서<h4 id="2-스래싱-thrashing">2. 스래싱 (Thrashing)</h4>
</li>
</ul>
</li>
<li>프로세스가 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능이 저해되는 문제<ul>
<li>지나치게 많은 페이징 때문</li>
</ul>
</li>
<li>동시에 실행되는 프로세스의 수를 아무리 늘려도 CPU 이용률이 높아지지는 않는다.</li>
<li>원인<ul>
<li>각 프로세스가 필요로 하는 최소한의 프레임 수가 보장되지 않았기 때문이다.</li>
</ul>
</li>
<li>해결 방안<ul>
<li>각 프로세스가 필요로 하는 최소한의 프레임 수를 파악하고,</li>
<li>프로세스들에게 적절한 프레임을 할당해야함<h3 id="프레임-할당">&lt;프레임 할당&gt;</h3>
<h4 id="1-균등-할당-equal-allocation">1. 균등 할당 (equal allocation)</h4>
</li>
</ul>
</li>
<li>가장 단순한 방식</li>
<li>모든 프로세스들에게 균등하게 프레임을 할당하는 방식<h4 id="2-비례-할당-proportional-allocation">2. 비례 할당 (proportional allocation)</h4>
</li>
<li>프로세스의 크기에 비례하여 프레임 할당</li>
<li>프로세스의 실행 과정을 교려하지 않기 때문에 정적할당 방식이라고 한다.</li>
<li>문제점<ul>
<li>크기가 큰 프로세스이긴 하지만, 많은 프레임이 필요없을수도..</li>
<li>필요한 프레임 수는 실행해봐야만 알 수 있다.</li>
</ul>
</li>
<li>해결방안<ul>
<li><strong>프로세스를 실행하는 과정에서 프레임을 결정</strong>하는 방식이 필요하다. </li>
<li><blockquote>
<p>작업 집합 모델 &amp; 페이지 폴드 빈도 기반 방식 (<strong>동적 할당 방식</strong>)</p>
</blockquote>
<h4 id="3-작업-집합-모델">3. 작업 집합 모델</h4>
</li>
</ul>
</li>
<li>스레싱의 원인이 과도한 페이징 이므로<ul>
<li><strong>CPU가 특정 시간동안 주로 참조한 페이지 갯수만큼만 프레임을 할당하기</strong></li>
</ul>
</li>
<li>프로세스가 일정 기간동안 참조한 페이지 집합을 기억하여 빈번한 페이지 교체 방지<ul>
<li><strong>작업 집합</strong>이란, 실행 중인 프로세스가 일정 시간 동안 참조한 페이지의 집합을 말한다.</li>
</ul>
</li>
<li>작업 집합 구하기<ul>
<li>프로세스가 참조한 페이지</li>
<li>시간 간격 필요</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/246adf7c-5d85-4878-b898-41dada6ba59f/image.png" alt=""></p>
<h4 id="4-페이지-폴트-빈도">4. 페이지 폴트 빈도</h4>
<ul>
<li>아래 두가지 가정에서 생긴 아이디어<ul>
<li>페이지 폴트율이 너무 높으면 그 프로세스는 너무 적은 프레임을 갖고 있다.</li>
<li>페이지 폴트율이 너무 낮으면 그 프로세스가 너무 많은 프레임을 갖고 있다.</li>
</ul>
</li>
<li>페이지 폴트율에 상한과 하한선을 정하고, 그 범위 안에서 프레임을 할당해주는 방식</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 리뷰 5 - 교착 상태(Dead Lock)]]></title>
            <link>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-5-%EA%B5%90%EC%B0%A9-%EC%83%81%ED%83%9CDead-Lock</link>
            <guid>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-5-%EA%B5%90%EC%B0%A9-%EC%83%81%ED%83%9CDead-Lock</guid>
            <pubDate>Mon, 03 Jun 2024 16:50:17 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고 자료 : 혼자 공부하는 컴퓨터구조 + 운영체제
사진 출처 : Operating System Concepts 10E</p>
</blockquote>
<h2 id="1-교착-상태란">1. 교착 상태란</h2>
<h3 id="식사하는-철학자-문제-dining-philosophers-problem">&lt;식사하는 철학자 문제 (Dining philosophers problem)&gt;</h3>
<h4 id="1-어떤-문제인가">1. 어떤 문제인가..</h4>
<p>1) 철학자들은 계속 생각하다가, 왼쪽 포크가 사용 가능하면 집어든다.
2) 철학자들은 계속 생각하다가, 오른쪽 포크가 사용 가능하면 집어든다.
3) 왼쪽과 오른쪽 포크를 모두 집어들면 정해진 시간동안 식사를 한다.
4) 식사 시간이 끝나면 오른쪽 포크를 내려둔다.
5) 오른쪽 포크를 내려놓은 뒤 왼쪽 포크를 내려둔다.
6) 다시 1)부터 반복한다. 
<img src="https://velog.velcdn.com/images/gb_leem/post/8acd2fab-ee0f-4522-baa6-a7e163570929/image.png" alt=""></p>
<h5 id="사진-출처-httpsenwikipediaorgwikidining_philosophers_problem">사진 출처: <a href="https://en.wikipedia.org/wiki/Dining_philosophers_problem">https://en.wikipedia.org/wiki/Dining_philosophers_problem</a></h5>
<h4 id="2-교착-상태란">2. 교착 상태란?</h4>
<ul>
<li>일어나지 않을 사건을 기다리며 진행이 멈춰 버리는 현상</li>
<li>모든 철학자가 1)을 수행하면 사용 가능한 오른쪽 포크가 없으므로 멈춰버림<h3 id="dead-lock-해결하기-위해서">&lt;dead lock 해결하기 위해서&gt;</h3>
<h4 id="1-개요">1. 개요</h4>
</li>
<li>교착 상태가 발생했을 때의 상황을 정확히 표현하기</li>
<li>교착 상태가 일어나는 근본적인 이유 이해하기<h4 id="2-자원할당-그래프">2. 자원할당 그래프</h4>
</li>
<li>교착 상태가 발생했을 때의 상황을 표현하는 그래프</li>
<li>교착 상태 발생 조건 파악 가능<ul>
<li>어떤 프로세스가 어떤 자원을 할당 받아 사용 중인지 확인 가능</li>
<li>어떤 프로세스가 어떤 자원을 기다리고 있는지 확인 가능</li>
</ul>
</li>
<li>그리는 방법<ul>
<li>프로세스는 원으로, 자원의 종류는 사각형으로 그리기</li>
<li>자원의 갯수는 사각형 내의 점으로 표현</li>
<li>프로세스가 할당 받은 자원은 화살표(r-&gt;p)로 표시</li>
<li>프로세스가 기다리는 자원은 반대 화살표(p-&gt;r)로 표시
<img src="https://velog.velcdn.com/images/gb_leem/post/194cbeac-201f-411f-9c6f-30b735aff4fe/image.png" alt=""></li>
</ul>
</li>
<li>교착 상태가 일어나는 자원할당 그래프는 원의 형태이다.
<img src="https://velog.velcdn.com/images/gb_leem/post/d39ee506-8535-4059-9492-86ec3f6e9d5c/image.png" alt=""><h4 id="3-교착상태가-발생할-조건">3. 교착상태가 발생할 조건</h4>
</li>
<li>네가지 조건!!</li>
<li><em>1) 상호 배제 (Mutual exclusion)*</em></li>
<li><blockquote>
<p>한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없는 상태</p>
</blockquote>
</li>
<li><em>2) 점유와 대기 (Hold and wait)*</em></li>
<li><blockquote>
<p>자원을 할당 받은 상태에서 다른 자원을 할당 받기를 기다리는 상태</p>
</blockquote>
</li>
<li><em>3 비선점 (No preemption)*</em></li>
<li><blockquote>
<p>어떤 프로세스도 다른 프로세스의 자원을 강제로 빼앗지 못하는 상태</p>
</blockquote>
</li>
<li><em>4) 원형 대기 (Circular wait)*</em></li>
<li><blockquote>
<p>프로세스들이 원의 형태로 자원을 대기하는 상태</p>
</blockquote>
</li>
<li>이 네가지 조건 중 하나라도 만족하지 않으면 교착 상태가 발생하지 않고, <strong>모두 만족</strong>해야 교착 상태가 발생한다.<h2 id="2-교착-상태-해결-방법">2. 교착 상태 해결 방법</h2>
<h3 id="예방-prevention">&lt;예방 (Prevention)&gt;</h3>
</li>
<li>애초에 교착 상태가 발생하지 않도록 하기</li>
<li>네가지 발생 조건 중 하나를 없애버리기</li>
<li>교착 상태가 발생하지 않음을 보장할 수는 있지만, 부작용이 있다...<h4 id="1-상호-배제-없애기">1. 상호 배제 없애기</h4>
</li>
<li>모든 자원을 공유가능하게 만들기?</li>
<li><blockquote>
<p>현실적으로 불가능</p>
</blockquote>
<h4 id="2-점유와-대기-없애기">2. 점유와 대기 없애기</h4>
</li>
<li>특정 프로세스에 자원을 모두 할당하거나, 아예 할당하지 않는 방식으로 배분</li>
<li><blockquote>
<p>자원의 활용률이 낮아지는 단점..</p>
</blockquote>
<h4 id="3-비선점-조건-없애기">3. 비선점 조건 없애기</h4>
</li>
<li><strong>선점이 가능한 자원(CPU)에 한해서 효과적임!</strong></li>
<li><blockquote>
<p>그러나 모든 자원이 선점 가능한 것은 아니다.</p>
</blockquote>
<h4 id="4-원형-대기-조건-없애기">4. 원형 대기 조건 없애기</h4>
</li>
<li>자원에 번호를 붙이고, 오름차순으로 할당하면 원형대기는 발생하지 않음</li>
<li>예를 들면 원형이 아닌 일자로 된 식탁에서 식사하는 방법</li>
<li>그러나</li>
<li><blockquote>
<p>자원에 번호를 붙이는 것은 어려운 작업이며</p>
</blockquote>
</li>
<li><blockquote>
<p>어떤 자원에 어떤 번호를 붙이느냐에 따라 활용률이 달라진다.</p>
</blockquote>
<h3 id="회피-avoidance">&lt;회피 (Avoidance)&gt;</h3>
<h4 id="1-개요-1">1. 개요</h4>
</li>
<li>교착 상태를 무분별한 자원 할당으로 인해 발생했다고 간주</li>
<li>교착 상태가 발생하지 않을 만큼 조심히 할당하기</li>
<li>배분할 수 있는 자원의 양을 고려하기<h4 id="2-교착-상태-회피">2. 교착 상태 회피</h4>
</li>
<li>안전 순서열<ul>
<li>교착 상태 없이 안전하게 프로세스들에 자원을 할당할 수 있는 순서</li>
</ul>
</li>
<li>안전 상태<ul>
<li>교착 상태 없이 모든 프로세스가 자원을 할당 받고 종료될 수 있는 상태</li>
<li>안전 순서열이 있는 상태</li>
</ul>
</li>
<li>불안전 상태<ul>
<li>교착 상태가 발생할 수도 있는 상태</li>
<li>안전 순서열이 없는 상태</li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th>프로세스</th>
<th>요구량</th>
<th>현재 사용량</th>
</tr>
</thead>
<tbody><tr>
<td>P1</td>
<td>10</td>
<td>5</td>
</tr>
<tr>
<td>P2</td>
<td>4</td>
<td>2</td>
</tr>
<tr>
<td>P3</td>
<td>9</td>
<td>2</td>
</tr>
</tbody></table>
<ul>
<li>예시 (안전 순서열이 존재하는 경우 - 위의 표 사용)<ul>
<li>할당 가능 자원 = 12</li>
<li>할당한 자원 = 5+2+2 = 9</li>
<li>남은 자원 = 12 - 9 = 3</li>
<li><strong>안전 순서열: P2-&gt;P1-&gt;P3</strong></li>
</ul>
</li>
<li><strong>안전 순서열에 따라 동작하는 순서</strong><ul>
<li>P2가 먼저 2만큼 할당<ul>
<li>할당한 자원 = 9+2 = 11</li>
<li>남은 자원 3 - 2 = 1</li>
</ul>
</li>
<li>요구한 자원을 모두 할당 받았으므로 P2의 자원 반환<ul>
<li>할당한 자원 = 11 - 4 = 7</li>
<li>남은 자원 = 1 + 4  = 5</li>
</ul>
</li>
<li>P1에 자원 할당<ul>
<li>할당한 자원 = 7 + 5 = 12</li>
<li>남은 자원 = 5 - 5 = 0</li>
</ul>
</li>
<li>P1자원 반환<ul>
<li>할당한 자원 = 12 - 10 = 2</li>
<li>남은 자원 = 0 + 10 = 10</li>
</ul>
</li>
<li>P3에 자원 할당<ul>
<li>할당한 자원 = 2 + 7 = 9</li>
<li>남은 자원 = 10 - 7 = 3</li>
</ul>
</li>
<li><strong>결론적으로 모든 프로세스가 자원을 할당 받았음!</strong><ul>
<li>만약 다른 순서로 동작했다면, 모든 프로세스가 자원을 할당 받지 못하는 상황이 발생한다.</li>
</ul>
</li>
</ul>
</li>
<li><strong>결론: 교착 상태 회피는 항상 안전 상태만을 유지하도록 자원을 할당하는 방식이다</strong></li>
<li>ex) 은행원 알고리즘</li>
</ul>
<h3 id="검출-후-회복detection-and-recovery">&lt;검출 후 회복(Detection and Recovery)&gt;</h3>
<ul>
<li>교착 상태의 발생을 인정하고 사후에 조치</li>
<li>프로세스가 자원을 요구하면 일단 할당, 교착 상태가 검출되면 회복<h4 id="1-선점을-통한-회복">1. 선점을 통한 회복</h4>
</li>
<li>교착 상태가 해결될 때까지 한 프로세스씩 자원을 몰아주는 방식<h4 id="2-프로세스-강제-종료를-통한-회복">2. 프로세스 강제 종료를 통한 회복</h4>
</li>
<li>교착 상태에 놓은 프로세스를 모두 강제 종료<ul>
<li>작업 내역을 잃을 위험이 있다.</li>
</ul>
</li>
<li>교착 상태가 해결될 때 까지 한 프로세스씩 강제 종료<ul>
<li>오버헤드가 발생<h3 id="무시">&lt;무시&gt;</h3>
<h4 id="1-타조-알고리즘">1. 타조 알고리즘</h4>
</li>
</ul>
</li>
<li>문제 발생의 확률이나 정도가 약하다면 무시하는 것이 더 효율적인 경우가 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 리뷰 4 - 동기화]]></title>
            <link>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-4-%EB%8F%99%EA%B8%B0%ED%99%94</link>
            <guid>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-4-%EB%8F%99%EA%B8%B0%ED%99%94</guid>
            <pubDate>Mon, 03 Jun 2024 08:22:47 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고 자료 : 혼자 공부하는 컴퓨터구조 + 운영체제
사진 출처 : Operating System Concepts 10E</p>
</blockquote>
<h2 id="1-동기화란">1. 동기화란</h2>
<h4 id="개요">개요</h4>
<ul>
<li>프로세스와 스레드는 동시 다발적으로 동작한다.</li>
<li>자원의 일관성을 위해 프로세스와 스레드의 동기화 필요</li>
</ul>
<h3 id="동기화의-의미">&lt;동기화의 의미&gt;</h3>
<h4 id="1-개요">1. 개요</h4>
<ul>
<li>공동의 목적을 위해 동시에 수행되는 프로세스들은</li>
<li>올바른 수행을 위해 <strong>동기화</strong>되어야 한다.<h4 id="2-프로세스의-동기화">2. 프로세스의 동기화</h4>
</li>
<li>프로세스(스레드)들의 수행 시기를 맞추는 것</li>
<li><strong>실행 순서 제어</strong> <ul>
<li>프로세스를 올바른 순서대로 실행하기</li>
</ul>
</li>
<li><strong>상호 배제</strong><ul>
<li>동시에 접근해서는 안되는 자원에 하나의 프로세스만 접근하게 하기<h3 id="동기화-예시">&lt;동기화 예시&gt;</h3>
<h4 id="1-실행-순서-제어를-위한-동기화">1. 실행 순서 제어를 위한 동기화</h4>
</li>
</ul>
</li>
<li><strong>Reader Writer Problem</strong><ul>
<li>Writer<ul>
<li>파일에 값을 저장하는(쓰는) 프로세스</li>
</ul>
</li>
<li>Reader<ul>
<li>파일에 저장된 값을 읽어들이는 프로세스</li>
</ul>
</li>
</ul>
</li>
<li>실행의 순서 지켜야함!<ul>
<li>reader 프로세스는 파일 안에 값이 존재한다는 특정 조건이 만족되어야 실행 가능</li>
<li>writer의 조건이 먼저 선행되어야 함<h4 id="2-상호-배제를-위한-동기화">2. 상호 배제를 위한 동기화</h4>
</li>
</ul>
</li>
<li><em>예시 1) Bank Account Problem*</em><ul>
<li><strong>공유가 불가능한 자원</strong>의 <strong>동시 사용</strong>을 피하기 위한 동기화</li>
</ul>
</li>
<li>예시<ul>
<li>프로세스 A<ul>
<li>계좌 잔액 읽고</li>
<li>잔액에 2만원 추가</li>
<li>저장</li>
</ul>
</li>
<li>프로세스 B<ul>
<li>계좌 잔액 읽고</li>
<li>잔액에 5만원 추가</li>
<li>저장</li>
</ul>
</li>
<li>문제가 되는 상황은 (처음 잔액 10만원)<ul>
<li>프로세스 A 진행 도중, 저장이 되기 전 context swtich 발생하고 (10만원)</li>
<li>프로세스 B도 저장이 되기 전까지 진행 후 context swtich 되어 (10만원)</li>
<li>프로세스 A의 값 저장 (12만원)</li>
<li>프로세스 B의 값 저장 한 상황 (15만원)</li>
<li>결과적으로 17만원이 아닌 15만원이 잔액이 된다.</li>
</ul>
</li>
<li>문제를 막으려면<ul>
<li><strong>한 번에 하나의 프로세스만 접근해야 하는 자원에 동시 접근을 막기</strong></li>
<li>프로세스 A가 다 끝난 후에 프로세스 B 실행</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong>예시 2) Producer &amp; Consumer Problem</strong>
<a href="https://github.com/GbLeem/Simple_cpp_OS/blob/main/03Synchronization/Synchronization_cpp/producer_and_consumer.cpp">producer and consumer c++ code</a></p>
<ul>
<li>Producer: 물건을 계속해서 생산하는 생산자</li>
<li>Consumer: 물건을 계속해서 소비하는 소비자 </li>
<li>총합: 공유 자원</li>
</ul>
<pre><code>총합 = 10 //전역변수

Producer()
{
    //버퍼에 데이터 삽입
    //총합 변수 1 증가
}

Consumer()
{
    //버퍼에서 데이터 꺼내기
    //총합 변수 1 감소
}</code></pre><ul>
<li>이러한 상태에서 생산자와 소비자를 각각 100,000 실행하면?<ul>
<li>0과는 다른 값이 되거나, 오류가 발생하기도 한다.</li>
<li>이유는?<ul>
<li><strong>동기화가 되지 않았기 때문에 발생한 문제</strong></li>
<li><strong>동시에 접근해서는 안되는 자원(공유자원)에 동시에 접근한 결과</strong></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="공유-자원과-임계-구역">&lt;공유 자원과 임계 구역&gt;</h3>
<h4 id="1-공유-자원-shared-resource">1. 공유 자원 (Shared Resource)</h4>
<ul>
<li>여러 프로세스 혹은 스레드가 공유하는 자원</li>
<li>ex)<ul>
<li>전역 변수, 파일, 입출력장치, 보조기억장치<h4 id="2-임계-구역-critical-section">2. 임계 구역 (Critical Section)</h4>
</li>
</ul>
</li>
<li>동시에 실행하면 문제가 발생하는 자원에 접근하는 <strong>코드 영역</strong></li>
<li>임계 구역에 진입하고자 하면, 진입한 프로세스 이외에는 대기해야 한다.<ul>
<li>프로세스 A가 실행중이면, 프로세스 B는 A가 끝날 때까지 대기했다가 실행</li>
</ul>
</li>
<li>ex)<ul>
<li>위 예시의 총합 변수, 잔액 변수<h4 id="3-race-condition">3. Race Condition</h4>
</li>
</ul>
</li>
<li>임계구역에 동시에 접근하여 자원의 일관성이 깨지는 상태<h4 id="4-운영체제가-임계구역-문제를-해결하는-세가지-원칙">4. 운영체제가 임계구역 문제를 해결하는 세가지 원칙</h4>
</li>
<li><strong>상호 배제</strong> (mutual exclusion)<ul>
<li>한 프로세스가 critical section에 진입했다면 다른 프로세스는 들어올 수 없다.</li>
</ul>
</li>
<li><strong>진행</strong> (progress)<ul>
<li>critical section에 어떤 프로세스도 진입하지 않았다면, 진입하고자 하는 프로세스는 들어갈 수 있어야 한다.</li>
</ul>
</li>
<li><strong>유한 대기</strong> (bounded waiting)<ul>
<li>한 프로세스가 critical section에 진입하고 싶다면, 언젠가는 critical section에 들어올 수 있어야 한다.</li>
</ul>
</li>
</ul>
<h2 id="2-동기화-기법">2. 동기화 기법</h2>
<h3 id="뮤텍스락-mutex-lock">&lt;뮤텍스락 (Mutex Lock)&gt;</h3>
<p><a href="https://github.com/GbLeem/Simple_cpp_OS/blob/main/03Synchronization/Synchronization_cpp/mutex_lock.cpp">mutex lock C++ code</a></p>
<h4 id="1-개요-1">1. 개요</h4>
<ul>
<li><p><strong>상호 배제</strong>를 위한 동기화 도구 (자물쇠 역할)</p>
</li>
<li><p>ex) 탈의실(임계구역)에 들어가는 손님(프로세스), 탈의실을 잠그는 자물쇠(뮤텍스락)</p>
<h4 id="2-뮤텍스락">2. 뮤텍스락</h4>
</li>
<li><p>코드로 구현해 보기</p>
<ul>
<li>전역변수 하나와 함수 두 개로 구현 가능</li>
<li>전역 변수 lock<ul>
<li>자물쇠 역할</li>
</ul>
</li>
<li>acquire 함수<ul>
<li>임계구역을 잠그는 역할</li>
<li>프로세스가 임계 구역에 진입하기 전에 호출</li>
<li>임계구역이 잠겨 있다면, 열릴 때 까지 계속 체크</li>
<li>임계구역이 열려 있다면, 임계구역을 잠그기</li>
</ul>
</li>
<li>release 함수<ul>
<li>임계 구역의 잠금을 해제하는 역할</li>
<li>임계 구역에서의 작업이 끝나고 호출</li>
<li>현재 잠긴 임계 구역을 열기</li>
</ul>
</li>
</ul>
</li>
<li><p>예시</p>
<pre><code>acquire()
{
  while(lock == true) //잠겨있다면,
         ;                //임계구역이 잠겨있는지 계속 확인
  lock = true;        //lock == false인 경우 임계구역 진입 후 lock을 다시 true로 만들기
}
</code></pre></li>
</ul>
<p>release()
{
    lock = false;        // 임계구역 작업 끝났으니 lock 해제
}</p>
<pre><code>#### 3. Busy Waiting
* `while(lock == true) ;` 
* 무한히 대기하면서 임계구역을 체크하는 것 -&gt; 좋은 방식은 아니다.
### &lt;세마포 (Semaphore)&gt;
[semaphore c++ code](https://github.com/GbLeem/Simple_cpp_OS/blob/main/03Synchronization/Synchronization_cpp/semaphore2.cpp)
#### 1. 개요
* 뮤텍스락 보다 일반화된 방식의 동기화 도구
* 공유 자원이 여러개 있는 경우에도 작용 가능
* **상호 배제와 실행 순서 동기화** 수행 가능
* ex) 이진 세마포, 카운팅 세마포 
#### 2. 카운팅 세마포
* 임계 구역 앞에서 멈춤 신호를 받으면 잠시 기다리기
* 임계 구역 앞에서 가도 좋다는 신호를 받으면 임계 구역 진입
* 코드로 구현해 보기
  * 전역변수 하나, 함수 두 개로 구현가능
  * 전역변수 S 
    * 임계 구역에 진입할 수 있는 프로세스의 갯수
    * 다른 말로 하면 사용 가능한 공유 자원의 갯수
  * wait 함수
    * 임계구역에 들어가도 좋은지, 기다려야 할지를 알려주는 함수
  * signal 함수
    * 임계구역 앞에서 기다리는 프로세스에 &#39;이제 가도 좋다&#39; 라고 신호를 주는 함수
* 예시</code></pre><p>wait()
{
    while(S&lt;=0) //임계 구역에 진입 못하면
    ;            //진입 가능한 자원 있을때 까지 확인
    S--;        //진입할 수 있다면, S하나 감소시키고 임계구역 진입
}</p>
<p>signal()
{<br>    S++;        //임계구역에서 작업을 마친 뒤 S를 1증가
}</p>
<pre><code>#### 3. 문제점과 해결 방안
* 문제점
  * 세마포 방식 또한 busy waiting을 한다
  * CPU 사이클의 낭비!
* 해결 방법
  * 사용할 수 있는 자원이 없을 경우 **대기 상태**로 만든다.
  (해당 프로세스의 PCB를 대기 큐에 삽입)
  * 사용할 수 있는 자원이 생긴 경우, 대기 큐의 프로세스를 **준비 상태**로 만듦 
  (해당 프로세스의 PCB를 대기 큐에서 꺼내 준비 큐에 삽입)
* 코드 예시</code></pre><p>wait()
{
    S--;
    if(S&lt;0)
    {
        add this process to Queue; //PCB를 대기큐에 삽입
        sleep();                   //대기 상태
    }
}</p>
<p>signal()
{
    S++;
    if(S&lt;=0)
    {
        remove a process p from Queue; //대기 상태에 있는 프로세스 제거
        wakeup(p);                       //프로세스 p를 대기 상태에서 준비 상태로 만들기
    }
}</p>
<pre><code>#### 4. 세마포의 실행 순서 동기화
* 예시
  * 변수 S를 0으로 두고 
  * 먼저 실행할 프로세스 뒤에 signal 함수
  * 다음에 실행할 프로세스 앞에 wait 함수를 붙이기
* 동작 순서
  * process1이 임계 구역 들어가서 실행 후 종료하면, siganl 함수를 통해 S가 1이 되고, 
  * process2가 S가 1인 것을 확인 후 실행
  * 결론적으로 p1 이 p2보다 먼저 실행된다.
### &lt;모니터&gt;
#### 1. 개요
* 매번 임계구역 앞 뒤로 wait(), signal() 호출하는 것이 번거롭다. 
* 아래의 이유들 때문에 실수 유발 가능
  * 세마포 누락
  * 함수 순서 바꿈
  * 함수 중복 사용
  * etc
* **상호 배제와 실행 순서 동기화** 수행 가능
* 모니터 안에는 하나의 프로세스만 있을 수 있다.
#### 2. 모니터의 상호 배제
* 인터페이스를 위한 큐
* 공유자원에 접근하고자 하는 프로세스를 큐에 삽입
* 큐에 삽입된 순서대로 공유 자원 이용
#### 3. 모니터의 실행 순서 제어를 위한 동기화
* 코드를 만든다면
  * 조건 변수 이용
    * 프로세스나 스레드의 실행 순서를 제어하기 위해 사용하는 특별한 변수
    * 조건변수에 대한 큐가 존재 (아래 그림의 빨간 네모칸)
  * 조건변수.wait()
    * 대기 상태로 변경, 조건 변수에 대한 큐에 삽입
  * 조건변수.signal()
    * wait()으로 대기 상태로 접어든 조건변수를 실행 상태로 변경
* 실행 순서 제어를 위한 동기화의 핵심!
  * **특정 프로세스가 아직 실행될 조건이 되지 않았을 때에는 wait을 통해 실행을 중단한다.**
  * **특정 프로세스가 실행될 조건이 충족되었을 때에는 signal을 통해 재개한다.**
#### 4. 모니터의 구조
![](https://velog.velcdn.com/images/gb_leem/post/46c77b66-8afc-4e61-b5d1-8a02ad9eda6b/image.png)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 리뷰 3 -CPU 스케줄링]]></title>
            <link>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-3-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</link>
            <guid>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-3-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</guid>
            <pubDate>Fri, 31 May 2024 09:29:59 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고 자료 : 혼자 공부하는 컴퓨터구조 + 운영체제
사진 출처 : Operating System Concepts 10E</p>
</blockquote>
<h2 id="1-cpu-스케줄링-개요">1. CPU 스케줄링 개요</h2>
<h3 id="cpu-스케줄링이란">&lt;CPU 스케줄링이란&gt;</h3>
<h4 id="1-개요">1. 개요</h4>
<ul>
<li>운영체제가 프로세스들에게 공정하고 합리적으로 CPU 자원을 배분하는 것</li>
</ul>
<h4 id="2-가장-공정한-방법">2. 가장 공정한 방법?</h4>
<ul>
<li>프로세스마다 우선순위를 생각해서 스케줄링 해야함<ul>
<li>ex) 입출력 작업이 많은 프로세스는 CPU 작업이 많은 프로세스보다 우선순위가 높다.<ul>
<li>입출력 작업이 많은 프로세스는 대기하는 시간이 길다.</li>
<li>즉, 미리 입출력 작업을 빠르게 끝내버리고 CPU 작업이 많은 프로세스에게 CPU를 몰빵하는 것<h3 id="프로세스-우선순위">&lt;프로세스 우선순위&gt;</h3>
<h4 id="1-개요-1">1. 개요</h4>
</li>
</ul>
</li>
</ul>
</li>
<li>PCB에 저장되어 우선순위 높은 것 부터 실행<h4 id="2-우선순위를-찾는-방법">2. 우선순위를 찾는 방법</h4>
</li>
<li>매번 모든 프로세스의 PCB를 찾아서 우선순위 높은 것을 찾는 것은 너무 낭비이고 오래걸린다. </li>
<li><blockquote>
<p>스케줄링 큐 이용</p>
</blockquote>
</li>
</ul>
<h3 id="스케줄링-큐">&lt;스케줄링 큐&gt;</h3>
<h4 id="1-개요-2">1. 개요</h4>
<ul>
<li>프로세스 마다 요구하는 자원들을 그에 따라 큐에 정리함</li>
<li>같은 큐 내에서도 우선순위 별로 처리한다<ul>
<li>cf)스케줄링 큐에서 큐는 반드시 FIFO는 아니다.</li>
</ul>
</li>
</ul>
<h4 id="2-준비-큐">2. 준비 큐</h4>
<ul>
<li>CPU를 이용하기 위해 기다리는 큐<h4 id="3-대기-큐">3. 대기 큐</h4>
</li>
<li>입출력장치를 이용하기 위해 기다리는 큐</li>
<li>같은 장치를 요구한 프로세스들은 같은 큐에서 대기<ul>
<li>ex) 프린터 대기 큐, 하드디스크 대기 큐</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/655f9ce4-7475-4396-87ad-77c5248df5e2/image.PNG" alt=""></p>
<h4 id="4-그렇다면">4. 그렇다면</h4>
<ul>
<li>현재 진행중인 프로세스보다 우선순위가 높은 프로세스가 ready queue에 들어오면 누구를 먼저 실행할 것인가?</li>
<li><blockquote>
<p>선점형 비선점형 스케줄링으로 결정</p>
</blockquote>
</li>
</ul>
<h3 id="선점형과-비선점형-스케줄링">&lt;선점형과 비선점형 스케줄링&gt;</h3>
<h4 id="1-개요-3">1. 개요</h4>
<ul>
<li>현재 한 프로세스가 실행중인데, 다른 프로세스가 너무 급해서 CPU를 할당해달라고 할 때</li>
<li><blockquote>
<p>현재 사용중인 프로세스로부터 CPU 자원 빼앗기</p>
</blockquote>
</li>
<li><blockquote>
<p>현재 사용중인 프로세스 끝날 때 까지 기다리기</p>
</blockquote>
<h4 id="2-선점형-스케줄링-preemptive">2. 선점형 스케줄링 (preemptive)</h4>
</li>
<li>프로세스마다 정해진 시간은 모두 지키고, 타이머 인터럽트 발생했을 때 CPU 넘겨주기</li>
<li>장점) <ul>
<li>한 프로세스의 독점을 막음</li>
<li>프로세스들에 골고루 자원 배분 가능</li>
</ul>
</li>
<li>단점) <ul>
<li>context switching이 많기 때문에 오버헤드 발생 가능<h4 id="3-비선점형-스케줄링-non-preemptive">3. 비선점형 스케줄링 (non-preemptive)</h4>
</li>
</ul>
</li>
<li>현재 진행중인 프로세스의 CPU 할당을 빼앗아서 급한 프로세스에게 바로 넘겨주기</li>
<li>장점)  <ul>
<li>context switch 오버헤드 적다</li>
</ul>
</li>
<li>단점) <ul>
<li>모든 프로세스에게 골고루 자원 배분 못할 수 있다.</li>
</ul>
</li>
</ul>
<h2 id="2-cpu-스케줄링-알고리즘">2. CPU 스케줄링 알고리즘</h2>
<h3 id="선입-선처리-first-come-first-served">&lt;선입 선처리 (First Come First Served&gt;</h3>
<ul>
<li>ready queue에 삽입된 순서대로 처리하는 비선점 스케줄링</li>
<li>동작방식<ul>
<li>먼저 CPU를 요청한 프로세스부터 CPU 할당</li>
</ul>
</li>
<li>단점) <ul>
<li>프로세스들이 기다리는 시간이 매우 길어질 수 있다.</li>
<li>ex) 먼저 실행된 프로세스의 실행시간이 길 때, 매우 오래 기다려야함<h3 id="최단-작업-우선-shortest-job-first">&lt;최단 작업 우선 (Shortest Job First)&gt;</h3>
</li>
</ul>
</li>
<li>FCFS의 단점을 해결한 방식</li>
<li>CPU 사용시간이 가장 짧은 프로세스부터 처리하는 방식<ul>
<li>비선점형 스케줄링</li>
<li>CPU 시간이 긴 프로세스를 나중에 실행하기<h3 id="라운드-로빈-round-robin">&lt;라운드 로빈 (Round Robin)&gt;</h3>
</li>
</ul>
</li>
<li><strong>FCFS + 타입 슬라이스</strong> 를 사용하는 방식<ul>
<li>타임 슬라이스 : 각 프로세스가 CPU를 사용할 수 있는 정해진 시간</li>
<li>타임 슬라이스의 크기를 잘 정하는 것이 중요</li>
</ul>
</li>
<li>동작 방식<ul>
<li>큐에 삽입된 순서대로 프로세스들이 CPU를 이용하다가 정해진 시간 만큼만 사용</li>
<li>만약 정해진 시간동안 못 끝냈다면, 다시 큐의 맨 뒤에 삽입<h3 id="최소-잔여-시간-우선-shortest-remaining-time">&lt;최소 잔여 시간 우선 (Shortest Remaining Time)&gt;</h3>
</li>
</ul>
</li>
<li><strong>SJF + Round Robin</strong> 방식</li>
<li>동작 방식<ul>
<li>정해진 시간만큼 CPU를 이용하되, 다음으로 CPU를 사용할 프로세스는 남은 작업 시간이 가장 적은 프로세스 선택<h3 id="우선순위">&lt;우선순위&gt;</h3>
</li>
</ul>
</li>
<li>동작방식<ul>
<li>프로세스들에 우선순위 부여하고 우선순위 높은 프로세스부터 실행</li>
<li>우선순위 같은 프로세스는 FCFS로 스케줄링</li>
</ul>
</li>
<li>SJF, SRT 스케줄링을 포함하는 개념<h4 id="cf-starvation">cf) Starvation</h4>
</li>
<li><strong>Starvation  현상이 발생할 수 있다는 근본적인 문제점 존재</strong><ul>
<li>우선순위가 높은 프로세스만 계속 실행되고, 낮은 프로세스는 계속 연기된다.</li>
</ul>
</li>
<li><strong>해결방안</strong><ul>
<li><strong>aging</strong> 기법 : 오랫동안 대기한 프로세스의 우선순위를 높여주는 방식<h3 id="다단계-큐-multilevel-queue">&lt;다단계 큐 (Multilevel queue)&gt;</h3>
</li>
</ul>
</li>
<li>우선순위 스케줄링의 발전된 형태</li>
<li>우선순위별로 준비 큐를 여러개 사용하는 스케줄링 방식<ul>
<li>큐가 여러 개이므로, 각자 다른 스케줄링 방식을 쓸 수 있다.</li>
</ul>
</li>
<li>동작방식<ul>
<li>우선순위가 가장 높은 큐에 있는 프로세스를 먼저 처리</li>
<li>우선순위가 가장 높은 큐가 비어있으면 그 다음 우선순위 큐에 있는 프로세스 처리</li>
</ul>
</li>
<li><strong>문제점</strong><ul>
<li>큐 간의 이동이 불가능 하므로,</li>
<li>결국 우선순위가 낮은 큐는 계속 실행을 못하는 starvation 발생 가능<h3 id="다단계-피드백-큐-multilevel-feedback-queue">&lt;다단계 피드백 큐 (Multilevel feedback queue&gt;</h3>
</li>
</ul>
</li>
<li>다단계 큐 스케줄링의 발전된 형태</li>
<li>큐 간의 이동이 가능한 다단계 큐 스케줄링</li>
<li>CPU를 많이 써야할수록 우선순위가 낮아진다.</li>
<li><strong>동작방식 (아래 사진 참고)</strong>
참고 : quantum = 8 이 우선순위가 가장 높은 것<ul>
<li>8의 quantum 동안 프로세스가 끝나면 ok</li>
<li>8의 quantum 동안 프로세스가 끝나지 않으면 CPU를 더 써야하는 것이므로 우선순위를 하나 내려준다.</li>
<li>반복하다보면, CPU 집중 프로세스는 우선순위가 낮아지고, IO 집중 프로세스의 우선순위는 높아진다.  </li>
</ul>
</li>
<li>다단계 피드백 큐에서도 <strong>aging</strong> 기법 사용 가능
<img src="https://velog.velcdn.com/images/gb_leem/post/405d3b04-042f-4295-925e-10214baa497a/image.PNG" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 리뷰 2 - 프로세스와 쓰레드]]></title>
            <link>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%93%B0%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%93%B0%EB%A0%88%EB%93%9C</guid>
            <pubDate>Thu, 30 May 2024 16:28:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고 자료 : 혼자 공부하는 컴퓨터구조 + 운영체제
사진 출처 : Operating System Concepts 10E</p>
</blockquote>
<h2 id="1-프로세스-개요">1. 프로세스 개요</h2>
<h3 id="실행-중인-프로그램-프로세스">&lt;실행 중인 프로그램, 프로세스&gt;</h3>
<h4 id="1-프로세스-확인하기">1. 프로세스 확인하기</h4>
<ul>
<li>foreground process: 사용자가 볼 수 있는 공간에서 실행</li>
<li>background process: 사용자가 볼 수 없는 공간에서 실행<ul>
<li>사용자와 상호작용 o </li>
<li>사용자와 상호작용 x - daemon, service</li>
</ul>
</li>
</ul>
<h3 id="프로세스-제어-블록">&lt;프로세스 제어 블록&gt;</h3>
<h4 id="1-개요">1. 개요</h4>
<ul>
<li>모든 프로세스는 실행을 위해 CPU가 필요하다. but CPU 자원은 한정되어있음</li>
<li>그 결과 한정된 시간만큼만 CPU 사용해야함<ul>
<li>자신의 차례에 정해진 시간만큼 CPU 이용</li>
<li><strong>타이머 인터럽트</strong> 발생하면 다음 프로세스 실행<h4 id="2-프로세스-제어-블록-pcb">2. 프로세스 제어 블록 (PCB)</h4>
</li>
</ul>
</li>
<li>빠르게 번갈아 수행되는 프로세스 관리를 위해 사용하는 <strong>자료구조</strong><ul>
<li>프로세스 관련 정보 저장 (상품에 달린 태그와 같은 역할)</li>
<li>프로세스 생성 시 <strong>커널 영역</strong>에 생성, 종료 시 폐기</li>
</ul>
</li>
<li><strong>PCB에 담기는 정보</strong><ul>
<li><strong>프로세스 ID (PID)</strong><ul>
<li>특정 프로세스 식별하기 위한 번호</li>
</ul>
</li>
<li><strong>레지스터 값</strong><ul>
<li>존재 이유: 마지막으로 어디까지 연산 수행했는지 기억하려고</li>
<li>자신의 실행 차례가 오면 이전까지 사용한 레지스터 중간 값을 모두 복원 (프로그램 카운터, 스택 포인터)</li>
</ul>
</li>
<li>프로세스 상태<ul>
<li>입출력 장치를 사용하기 위해 기다리는 상태</li>
<li>CPU를 사용하기 위해 기다리는 상태</li>
<li>CPU 이용중인 상태 등</li>
</ul>
</li>
<li>CPU 스케줄링 정보<ul>
<li>프로세스가 언제, 어떤 순서로 CPU 할당 받을 것인지</li>
</ul>
</li>
<li>메모리 정보<ul>
<li>프로세스가 어느 주소에 저장되어 있는지</li>
<li><strong>페이지 테이블 정보</strong></li>
</ul>
</li>
<li>사용한 파일과 입출력 장치 정보<ul>
<li>할당된 입출력 장치, 열린 파일 정보 등</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="문맥-교환context-switch">&lt;문맥 교환(context switch)&gt;</h3>
<h4 id="1-context-switch-과정">1. Context Switch 과정</h4>
<ul>
<li>프로세스 A에서 프로세스 B로 실행 순서가 넘어가면?<ul>
<li>기존에 실행되던 프로세스 A의 중간 정보(context)를 백업</li>
<li>프로세스 B의 context 복구</li>
<li>다시 프로세스 A 차례가 오면 중간 정보를 기반으로 다시 복구<h4 id="2-context-switch">2. Context Switch</h4>
</li>
</ul>
</li>
<li><strong>기존의 실행 중인 프로세스 문맥을 백업하고, 새로운 프로세스 실행을 위해 문맥을 복구하는 과정</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/335d2bd3-1009-43ef-9d63-b74a7d63a541/image.PNG" alt=""></li>
</ul>
<h3 id="프로세스의-메모리-영역">&lt;프로세스의 메모리 영역&gt;</h3>
<h4 id="1-코드-영역-텍스트-영역">1. 코드 영역 (텍스트 영역)</h4>
<ul>
<li>실행할 수 있는 코드 (기계어로 이루어진 명령어 저장)</li>
<li>데이터가 아닌 CPU가 실행할 명령어가 담겨있음 (read-only)</li>
<li>크기 고정 (정적 할당 영역)<h4 id="2-데이터-영역">2. 데이터 영역</h4>
</li>
<li>잠깐 썻다가 없어지는 데이터가 아니라 프로그램이 실행되는 동안 유지할 데이터 저장</li>
<li>크기 고정 (정적 할당 영역)</li>
<li>ex) 전역변수<h4 id="3-힙-영역">3. 힙 영역</h4>
</li>
<li>프로그램을 만드는 사용자, 즉 프로그래머가 <strong>직접 할당할 수 있는 저장공간</strong><ul>
<li>할당하면, 언젠가는 반환(해제)를 해주어야 함</li>
<li>cf) garbage collection</li>
</ul>
</li>
<li>동적 할당 영역<ul>
<li>일반적으로 낮은 주소에서 높은 주소로 할당<h4 id="4-스택-영역">4. 스택 영역</h4>
</li>
</ul>
</li>
<li>데이터가 일시적으로 저장되는 공간<ul>
<li>잠깐 쓰다가 말 값들이 저장되는 공간</li>
</ul>
</li>
<li>ex) 매개변수, 지역변수</li>
<li>동적 할당 영역<ul>
<li>일반적으로 높은 주소에서 낮은 주소로 할당</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/9fe43d2a-2ba4-4a29-8224-40006c3eca59/image.PNG" alt=""></p>
<h2 id="2-프로세스-상태와-계층-구조">2. 프로세스 상태와 계층 구조</h2>
<h3 id="프로세스-상태">&lt;프로세스 상태&gt;</h3>
<h4 id="1-생성-상태">1. 생성 상태</h4>
<ul>
<li>이제 막 메모리에 적재되어 PCB를 할당 받은 상태</li>
<li>준비가 완료되었다면, <strong>준비 상태</strong>로 이동<h4 id="2-준비-상태">2. 준비 상태</h4>
</li>
<li>당장이라도 CPU를 할당받아서 실행할 수 있지만, </li>
<li>자신의 차례가 아니기에 기다리는 상태, 자신의 차례가 된다면 <strong>실행 상태</strong>로 이동 (<strong>디스패치</strong>)<h4 id="3-실행-상태">3. 실행 상태</h4>
</li>
<li>CPU를 할당 받아 실행 중인 상태</li>
<li>할당된 시간 모두 사용 시 (타이머 인터럽트 발생) <strong>준비 상태</strong>로 이동</li>
<li>실행 도중 입출력장치 사용하면, 입출력 작업이 끝날 때까지 <strong>대기 상태</strong>로 이동<h4 id="4-대기-상태">4. 대기 상태</h4>
</li>
<li>프로세스가 실행 도중 입출력 장치를 사용하는 경우</li>
<li>입출력 작업은 CPU에 비해 느리기 때문에 대기 상태로 접어둠</li>
<li>입출력 작업이 끝나면 (입출력 완료 인터럽트 발생하면) <strong>준비 상태</strong>로 이동<h4 id="5-종료-상태">5. 종료 상태</h4>
</li>
<li>프로세스가 종료된 상태</li>
<li>PCB, 프로세스의 메모리 영역 정리</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/37eea519-88b5-4ba8-9bcf-6cfdc1349cf1/image.PNG" alt=""></p>
<h3 id="프로세스-계층-구조">&lt;프로세스 계층 구조&gt;</h3>
<ul>
<li>프로세스 실행 도중 (시스템 호출을 통해) 다른 프로세스 생성 가능<ul>
<li>cf) 윈도우는 계층 구조 아님</li>
</ul>
</li>
<li>새 프로세스를 생성한 프로세스: 부모 프로세스</li>
<li>부모 프로세스에 의해 생성된 프로세스: 자식 프로세스<ul>
<li>부모 프로세스와 자식 프로세스는 별개의 프로세스이므로 PID가 다르다.</li>
<li>일부 OS는 자식 프로세스 PCB에 부모 프로세스 PID (PPID)를 명시하기도 함</li>
</ul>
</li>
<li>부모 -&gt; 자식 -&gt; 자식 -&gt; ... : 계층 구조 형성</li>
</ul>
<h3 id="프로세스-생성-기법">&lt;프로세스 생성 기법&gt;</h3>
<h4 id="1-개요-1">1. 개요</h4>
<ul>
<li>cf) 윈도우 운영체제와 관련은 없음</li>
<li>질문<ul>
<li>부모 프로세스는 자식 프로세스를 어떻게 만들어내는가</li>
<li>자식 프로세스는 어떻게 자신만의 코드를 실행하는가</li>
</ul>
</li>
<li>답<ul>
<li><strong>복제와 옷 갈아입기</strong></li>
<li>부모 프로세스는 <strong>fork</strong> 시스템 호출을 통해 자신의 복사본을 자식 프로세스로 생성 (복제)</li>
<li>자식 프로세스는 <strong>exec</strong> 시스템 호출을 통해 자신의 메모리 공간을 다른 프로그램으로 교체 (옷 갈아입기)</li>
</ul>
</li>
</ul>
<h4 id="2-프로세스-생성-기법">2. 프로세스 생성 기법</h4>
<ul>
<li><strong>fork 시스템 호출</strong><ul>
<li>복사본(자식 프로세스) 생성, 부모와 같은 복사본<ul>
<li><strong>but PID와 저장된 메모리 공간은 다르다</strong></li>
</ul>
</li>
<li>부모 프로세스의 자원 상속<ul>
<li>부모 프로세스의 메모리 영역을 복사해서 가져온다.</li>
</ul>
</li>
</ul>
</li>
<li><strong>exec 시스템 호출</strong><ul>
<li>메모리 공간을 새로운 프로그램으로 덮어쓰기</li>
<li><strong>코드/데이터 영역</strong>은 실행할 프로그램 내용으로 바뀜</li>
<li><strong>나머지 영역</strong>은 초기화<h2 id="3-스레드">3. 스레드</h2>
<h3 id="스레드란">&lt;스레드란&gt;</h3>
<h4 id="1-스레드란">1. 스레드란</h4>
</li>
</ul>
</li>
<li><strong>프로세스를 구성하는 실행 흐름의 단위</strong><ul>
<li>하나의 프로세스는 하나 이상의 스레드를 가질 수 있다.</li>
</ul>
</li>
<li>단일 스레드 프로세스<ul>
<li>실행 흐름이 하나인 프로세스</li>
</ul>
</li>
<li>멀티 스레드 프로세스<ul>
<li>프로세스를 이루는 여러 명령어 동시 실행 가능
<img src="https://velog.velcdn.com/images/gb_leem/post/84d3ee94-686c-4e81-8f7c-a20c4bd7a81b/image.PNG" alt=""></li>
</ul>
</li>
</ul>
<h4 id="2-스레드의-구성-요소">2. 스레드의 구성 요소</h4>
<ul>
<li>스레드 ID</li>
<li>레지스터 값 (프로그램 카운터)</li>
<li>스택 값</li>
<li><strong>실행에 필요한 최소한의 정보</strong><ul>
<li>코드, 데이터 영역, 자원을 공유함 (위 사진 참고)</li>
</ul>
</li>
</ul>
<h3 id="멀티-프로세스와-멀티-스레드">&lt;멀티 프로세스와 멀티 스레드&gt;</h3>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/71f4ea76-3ff5-4105-8a09-bcd7f149d3fc/image.PNG" alt=""></p>
<h4 id="1-멀티-프로세스">1. 멀티 프로세스</h4>
<ul>
<li><strong>동일한 작업을 수행하는 단일 스레드 프로세스 여러 개 실행</strong> (a)</li>
<li>프로세스 끼리는 자원 공유 x<ul>
<li>프로세스 fork하면, 모든 자원이 복제된다.</li>
<li>저장된 메모리 주소를 제외하고 모든 것이 동일한 프로세스가 메모리에 적재된다. (중복!)</li>
<li>cf) 실제로는 &quot;copy on write&quot; 해서 중복 저장을 없애주긴 함!</li>
</ul>
</li>
<li>독립적으로 실행된다.</li>
<li><strong>IPC</strong> : 프로세스 간 통신<ul>
<li>프로세스간에 자원을 주고 받을 수 있기는 하다.</li>
<li>스레드 간 통신 보다는 어려움<ul>
<li><strong>파일, 공유 메모리</strong>를 통해서 IPC 수행<h4 id="2-멀티-스레드">2. 멀티 스레드</h4>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>하나의 프로세스를 여러 스레드로 실행</strong> (b)</li>
<li>스레드 끼리는 같은 프로세스 내 자원 공유 o<ul>
<li>레지스터 값, 스택 값 만 가지고,</li>
<li>코드, 데이터, 힙, 파일 영역은 공유한다.</li>
</ul>
</li>
<li>협력과 통신에 유리하다.<ul>
<li>하나의 스레드가 문제 생기면, 전체 프로세스에 문제가 생길 가능성이 있다. (단점)</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[운영체제 리뷰 1 - 운영체제란]]></title>
            <link>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-1</link>
            <guid>https://velog.io/@gb_leem/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A6%AC%EB%B7%B0-1</guid>
            <pubDate>Thu, 30 May 2024 08:58:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고 자료 : 혼자 공부하는 컴퓨터구조 + 운영체제
사진 출처 : Operating System Concepts 10E</p>
</blockquote>
<h2 id="1-운영체제를-알아야-하는-이유">1. 운영체제를 알아야 하는 이유</h2>
<h3 id="운영체제란">&lt;운영체제란&gt;</h3>
<h4 id="1-운영체제는">1. 운영체제는</h4>
<ul>
<li>실행할 프로그램에 필요한 자원을 할당하고</li>
<li>프로그램이 올바르게 실행되도록 돕는</li>
<li>특별한 <strong>프로그램</strong> <ul>
<li>프로그램이기 때문에 메모리에 저장되어야 한다</li>
<li>운영체제는 <strong>커널 영역</strong>에 적재된다.</li>
<li>cf) 응용 프로그램(application)은 <strong>사용자 영역</strong>에 적재</li>
</ul>
</li>
<li><strong>하드웨어</strong>와 <strong>응용 프로그램</strong> 사이에서 우리가 편리하게 사용할 수 있도록 도와준다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/57594490-61d1-4218-9d4a-b72a4d802a01/image.PNG" alt=""></p>
<h4 id="2-운영체제의-메모리-관리">2. 운영체제의 메모리 관리</h4>
<ul>
<li>운영체제는 응용 프로그램이 실행되거나 종료될 때 적절한 메모리에 할당하거나 해제시킨다.</li>
</ul>
<h4 id="3-운영체제의-cpu-관리">3. 운영체제의 CPU 관리</h4>
<ul>
<li>응용 프로그램이 동시에 실행되고 있더라도, 각 프로그램의 우선순위에 따라 CPU 사용량을 조절해준다.</li>
</ul>
<h4 id="4-운영체제의-입출력장치-관리">4. 운영체제의 입출력장치 관리</h4>
<ul>
<li>프린터, 키보드 등 우선순위 관리</li>
<li>+)보조 기억 장치에 있는 것을 파일과 폴더로 관리</li>
</ul>
<h4 id="5-운영체제는-정부-와-유사한-일을-한다">5. 운영체제는 &#39;정부&#39; 와 유사한 일을 한다.</h4>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/2222b8fb-a9ec-46a9-9a5f-af011210b00f/image.PNG" alt=""></p>
<h3 id="운영체제를-알아야-하는-이유">&lt;운영체제를 알아야 하는 이유&gt;</h3>
<h4 id="1-개발자가-하드웨어를-직접-조작하는-일-없이-편리하게-개발할-수-있게-해준다">1. 개발자가 하드웨어를 직접 조작하는 일 없이 편리하게 개발할 수 있게 해준다.</h4>
<ul>
<li>운영체제는 사용자를 위한 프로그램이 아니라 프로그램을 위한 프로그램이다.</li>
<li>문제가 생긴다면 운영체제가 도움을 준다. <ul>
<li>프로그램이기 때문에 오류 메세지를 준다. </li>
</ul>
</li>
</ul>
<h2 id="2-운영체제의-큰-그림">2. 운영체제의 큰 그림</h2>
<h3 id="커널이란">&lt;커널이란?&gt;</h3>
<h4 id="1-커널">1. 커널</h4>
<ul>
<li>운영체제의 핵심 서비스를 담당하는 부분<h4 id="2-ui">2. UI</h4>
</li>
<li><strong>OS에는 속하지만 커널에는 속하지 않는 기능</strong></li>
<li>사용자와 컴퓨터 간의 <strong>통로</strong>일 뿐</li>
<li>ex) 그래픽 유저 인터페이스, 커맨드라인 인터페이스<h3 id="운영체제의-서비스-종류">&lt;운영체제의 서비스 종류&gt;</h3>
<h4 id="1-프로세스-관리">1. 프로세스 관리</h4>
</li>
<li><strong>프로세스</strong> <ul>
<li>프로세스 == 실행중인 프로그램</li>
<li>동시다발적으로 생성/실행/삭제되는 프로세스들을 관리해야 함!  <h4 id="2-자원-접근-및-할당">2. 자원 접근 및 할당</h4>
</li>
</ul>
</li>
<li>CPU<ul>
<li>CPU 스케줄링: 어떤 프로세스를 먼저, 얼마나 오래 실행할지</li>
</ul>
</li>
<li>메모리<ul>
<li>적재할 빈 메모리 공간을 어떻게 찾을지, 다 적재해야 하는지..</li>
<li>페이징, 스와핑</li>
</ul>
</li>
<li>입출력장치<ul>
<li>하드웨어 인터럽트 서비스 루틴<h4 id="3-파일-시스템-관리">3. 파일 시스템 관리</h4>
</li>
</ul>
</li>
<li>관련된 정보를 파일이라는 단위로 저장 장치에 보관</li>
<li>파일을 묶어 폴더(디렉토리) 단위로 저장 장치에 보관</li>
</ul>
<h3 id="시스템-콜과-이중-모드">&lt;시스템 콜과 이중 모드&gt;</h3>
<h4 id="1-사용자가-실행하는-프로그램은-자원에-직접-접근할-수-있을까">1. 사용자가 실행하는 프로그램은 자원에 직접 접근할 수 있을까?</h4>
<ul>
<li>NO! 자원에 직접 접근은 위험하다.</li>
<li>그렇기 때문에 OS는 응용 프로그램이 자원에 접근하여 할 때 <strong>OS를 통해서만</strong> 접근하도록 보호해준다.</li>
</ul>
<h4 id="2-이중모드">2. 이중모드</h4>
<ul>
<li>CPU가 명령어를 실행하는 모드의 두 가지 (이중모드)<ul>
<li>사용자 모드<ul>
<li>OS 서비스 제공 x</li>
<li>커널 영역 코드 실행 x</li>
<li>자원 접근 x</li>
</ul>
</li>
<li>커널 모드<ul>
<li>OS 서비스 제공 o</li>
<li>자원 접근 o</li>
</ul>
</li>
</ul>
</li>
<li><strong>플래그 레지스터</strong><ul>
<li>슈퍼바이저 플래그를 통해 커널 모드인지 사용자 모드인지 확인한다.</li>
</ul>
</li>
</ul>
<h4 id="3-시스템-호출">3. 시스템 호출</h4>
<ul>
<li><strong>커널 모드로 전환</strong>하여 실행하기 위해 호출!<ul>
<li>운영체제한테 도움 청하기!</li>
</ul>
</li>
<li>일종의 소프트웨어 <strong>인터럽트</strong>
1) 시스템 호출
2) 운영체제 코드 실행 (하드웨어 접근 코드 실행)
3) 시스템 호출 복귀 (사용자 모드로 간다)
<img src="https://velog.velcdn.com/images/gb_leem/post/9ac38093-5b11-4f0e-a69a-e4f133ae2157/image.PNG" alt=""></li>
<li>시스템 호출 명령어들
<img src="https://velog.velcdn.com/images/gb_leem/post/f508a03a-6501-406c-ac36-875efdfab2fd/image.PNG" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Unreal Engine - Basic1]]></title>
            <link>https://velog.io/@gb_leem/Unreal-Engine-Basic1</link>
            <guid>https://velog.io/@gb_leem/Unreal-Engine-Basic1</guid>
            <pubDate>Sun, 26 May 2024 10:00:11 GMT</pubDate>
            <description><![CDATA[<h2 id="introduction">Introduction</h2>
<ul>
<li>Objects : collection of data </li>
<li>Actor : object on the level</li>
<li>Components : objects that can go on an actors<h2 id="add-impulse">Add Impulse</h2>
<img src="https://velog.velcdn.com/images/gb_leem/post/dce43c86-7f49-42db-832d-7418d22aa296/image.PNG" alt=""></li>
<li>Vel Change 체크하면, 물체의 질량에 관계없이 Impulse 에 가한 값만큼 움직인다.</li>
<li><blockquote>
<p>400cm/s</p>
</blockquote>
</li>
</ul>
<h2 id="f8">F8</h2>
<ul>
<li>game을 플레이하는 플레이어에서 탈출해서 조작할 때</li>
</ul>
<h2 id="pawn-rotation">Pawn Rotation</h2>
<ul>
<li>get actor rotation
언리얼 카메라와 pawn 의 rotation은 기본적으로 연동되어있지 않다.</li>
<li><strong>get control rotation</strong>
카메라의 rotation 반영함</li>
</ul>
<h2 id="get-forward-vector">Get Forward Vector</h2>
<ul>
<li>크기 1짜리</li>
</ul>
<h2 id="geometry">Geometry</h2>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/c76e72c2-d1ba-4c56-b7f8-216653a84f84/image.PNG" alt="">
<img src="https://velog.velcdn.com/images/gb_leem/post/c685b530-85a6-4a15-bea6-d483edf7c5c9/image.PNG" alt=""></p>
<ul>
<li>subtractive 사용해서 창문 처럼 뚫을 수 있다.<h2 id="fix-collision">Fix Collision</h2>
</li>
<li>mesh가 여러 개가 바짝 붙어있을 때 충돌 때문에 불안정 한 현상 고치기 (아래 사진처럼 만들기)
<img src="https://velog.velcdn.com/images/gb_leem/post/a958e59f-9c74-4ab5-b08a-1daa490fb307/image.PNG" alt="">
1) 바꾸려고 하는 매시 선택후 collision 선택
2) remove collision 한다음 simplified collision 선택하기
<img src="https://velog.velcdn.com/images/gb_leem/post/c25a75ab-42b7-4218-9d09-a66ecea14776/image.png" alt=""></li>
</ul>
<h2 id="pure-function">Pure Function</h2>
<ul>
<li>A function with no side effect<ul>
<li>side effect : observable effect of a function</li>
</ul>
</li>
<li>NO EXECUTION PIN!</li>
<li>only return values</li>
<li>ex)<ul>
<li>get ammo</li>
<li>get actor forward vector</li>
<li>math function (*, -, &gt;...)</li>
</ul>
</li>
<li>예시
<img src="https://velog.velcdn.com/images/gb_leem/post/8b4171be-c336-4f35-880d-63f1a8d8b982/image.PNG" alt="">
<img src="https://velog.velcdn.com/images/gb_leem/post/420a299e-4ea1-4478-92e0-120c91e48f67/image.PNG" alt="">
<img src="https://velog.velcdn.com/images/gb_leem/post/c1de0dd2-f96e-4b4b-9365-1b51a6bf6623/image.PNG" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[C++ 다형성, 상속]]></title>
            <link>https://velog.io/@gb_leem/C-%EB%8B%A4%ED%98%95%EC%84%B1-%EC%83%81%EC%86%8D</link>
            <guid>https://velog.io/@gb_leem/C-%EB%8B%A4%ED%98%95%EC%84%B1-%EC%83%81%EC%86%8D</guid>
            <pubDate>Fri, 24 May 2024 15:38:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>원본 코드:
<a href="https://github.com/GbLeem/CodingTest2024/blob/main/CPP/Inheritance/inheritance_test.cpp">https://github.com/GbLeem/CodingTest2024/blob/main/CPP/Inheritance/inheritance_test.cpp</a></p>
</blockquote>
<h3 id="함수-오버라이딩">함수 오버라이딩</h3>
<ul>
<li>덮어쓰기라고 생각하면 편함<ul>
<li>C++는 기본적으로 정적 바인딩한다.</li>
</ul>
</li>
<li>예시 코드 <code>Bar()</code> 함수가 overriding 된 함수이며 실행 예시를 보면 <strong>클래스 type</strong>에 따라 실행된다.</li>
</ul>
<h3 id="가상함수">가상함수</h3>
<ul>
<li>다형성의 가장 핵심이 되는 것</li>
<li>동적 바인딩</li>
<li>가상 테이블이 생성되며, 이는 <strong>클래스</strong>마다 하나를 가진다.</li>
<li>예시 코드 <code>Foo()</code> 함수가 가상함수이며 실행 예시를 보면 <strong>실제로 가리키는 것</strong>에 따라 실행된다.</li>
</ul>
<h3 id="상속">상속</h3>
<ul>
<li>예시 코드 <code>d</code> 는 Derived 타입변수이며 Base로 부터 상속을 받았으므로, Base Class의 멤버함수 OnlyBase()를 쓸 수 있다.<h3 id="예시-코드">예시 코드</h3>
<pre><code>#include &lt;iostream&gt;
using namespace std;
</code></pre></li>
</ul>
<p>class Base
{
public:
    virtual void Foo()
    {
        printf(&quot;Base::Foo\n&quot;);
    }
    void Bar()
    {
        printf(&quot;Base::Bar\n&quot;);
    }
    void onlybase()
    {
        cout &lt;&lt; &quot;onlybase\n&quot;;
    }
};</p>
<p>class Derived : public Base
{
public:
    virtual void Foo()
    {
        printf(&quot;Derived::Foo\n&quot;);
    }
    void Bar() //Overriding
    {
        printf(&quot;Derived::Bar\n&quot;);
    }
    void OnlyDerived()
    {
        cout &lt;&lt; &quot;only derived\n&quot;;
    }
};</p>
<p>int main()
{
    Derived* d = new Derived(); //여기서 base 묵시적으로 만들어짐
    Base* b = reinterpret_cast&lt;Base<em>&gt;(d);
    Base</em> b2 = new Base();</p>
<pre><code>d-&gt;Foo(); //Derived::Foo
d-&gt;Bar(); //Derived::Bar
d-&gt;onlybase();
d-&gt;OnlyDerived();
cout &lt;&lt; &quot;\n&quot;;

b-&gt;Foo(); //Derived::Foo    
b-&gt;Bar(); //Base::Bar
b-&gt;onlybase();
cout &lt;&lt; &quot;\n&quot;;

b2-&gt;Foo(); //Base::Foo
b2-&gt;Bar(); //Base::Bar
b2-&gt;onlybase();</code></pre><p>}</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test - Dynamic Programming]]></title>
            <link>https://velog.io/@gb_leem/Coding-Test-Dynamic-Programming</link>
            <guid>https://velog.io/@gb_leem/Coding-Test-Dynamic-Programming</guid>
            <pubDate>Thu, 16 May 2024 15:51:17 GMT</pubDate>
            <description><![CDATA[<h2 id="dynamic-programming">Dynamic Programming</h2>
<h3 id="0-intro">0. intro</h3>
<ul>
<li>DP 문제는 뭔가 작은 값들을 계산하다 보면 결국 큰 값도 결과가 나올 수 있을 것 같은 문제에서 쓰기</li>
<li>시간 복잡도 줄이기</li>
<li>prefix sum 기법도 있다. (BOJ 11659)</li>
</ul>
<h3 id="1-dp-문제를-위한-흐름">1. DP 문제를 위한 흐름</h3>
<p>1) 테이블 정의하기
2) 점화식 찾기
3) 초기값 찾기</p>
<h3 id="2-dp를-풀-때-팁">2. DP를 풀 때 팁</h3>
<p><em>(정답은 아니고 풀다가 생각을 정리한 것 들입니다.)</em></p>
<ul>
<li>점화식을 만들 때 d[1] 부터 계산해 나가면서 규칙 찾아내는 식으로 풀기</li>
<li>단순히 1차원 배열로 해결이 안될 것 같으면 2차원 배열도 생각해보기</li>
<li>점화식이 잘 안 만들어 지면 맨 끝값부터 처리하는 것도 생각해보자 (BOJ 15486)</li>
<li>점화식 만들 때는 <strong>현재 시점</strong>에 어떠한 행동을 했다고 가정했을 때, <strong>과거의 값</strong>들에 대한 비교를 통해 현재 점화식 값을 설정한다.</li>
<li>초기값은 for문을 돌리면서 초기값으로 필요할 것들을 직접 대입해서 설정해주기</li>
</ul>
<h3 id="3-dp-문제-예시">3. DP 문제 예시</h3>
<h4 id="예시1-boj-2579-계단-오르기">예시1) BOJ 2579 계단 오르기</h4>
<pre><code>#include &lt;iostream&gt;
using namespace std;

int n;
int board[305];
int d[305][305];

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin &gt;&gt; n;
    for (int i = 1; i &lt;= n; ++i)
        cin &gt;&gt; board[i];

    d[1][1] = board[1];
    d[1][2] = 0;
    d[2][1] = board[2];
    d[2][2] = board[1] + board[2];

    for (int i = 3; i &lt;= n; ++i)
    {
        d[i][1] = max(d[i - 2][2], d[i - 2][1]) + board[i];
        d[i][2] = d[i - 1][1] + board[i];
    }
    cout &lt;&lt; max(d[n][1], d[n][2]);
}</code></pre><ul>
<li>점화식 부분)<ul>
<li>d[i][j] : i번째 계단을 밟은것 / j번 연속 밟은 것</li>
<li>d[i][1]<ul>
<li>현재 i 번째 계단을 밟았다고 (현재시점) 했을 때 j는 1이므로 한번 연속 밟았으니, 하나 전 계단은 밟을 수 없음 (하나 전 계단도 밟았으면 j가 2여야 하므로)</li>
<li>두개 전 계단을 밟았을 때 (과거시점) 연속 1번 밟은 것과 연속 2번 밟은 것 중 큰 값을 가져오고</li>
<li>마지막으로 현재의 계단을 밟았을 때 값을 더해준다.</li>
</ul>
</li>
<li>d[i][2]<ul>
<li>현재 i 번째 계단을 밟았다고 (현재시점) 했을 때, 연속 두번 밟았으므로</li>
<li>하나 전 계단 (과거시점) 은 무조건 밟아야한다. </li>
<li>마지막으로 현재 계단에 대한 값도 더해주면 된다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="예시2-boj-9465-스티커">예시2) BOJ 9465 스티커</h4>
<pre><code>#include&lt;iostream&gt;
using namespace std;

int t, n;
int board[2][100005];
int d[100005][3]; //(값, 마지막으로 선택한 타일)

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin &gt;&gt; t;

    while (t--)
    {
        cin &gt;&gt; n;

        for (int i = 0; i &lt; 2; ++i)
            fill(board[i], board[i] + n, 0);

        for (int i = 0; i &lt; n; ++i)
            fill(d[i], d[i] + 3, 0);

        for (int i = 0; i &lt; 2; ++i)
        {
            for (int j = 0; j &lt; n; ++j)
                cin &gt;&gt; board[i][j]; // board[0][1] 은 첫줄 2번째
        }

        d[0][0] = 0;
        d[0][1] = board[0][0];
        d[0][2] = board[1][0];    

        if (n == 1)
            cout &lt;&lt; max(max(d[0][0], d[0][1]), d[0][2]) &lt;&lt; &quot;\n&quot;;
        else
        {
            for (int i = 1; i &lt; n; ++i)
            {
                //첫줄 붙이거나 둘째줄 붙이거나 안붙이거나
                d[i][0] = max(max(d[i - 1][1], d[i - 1][2]), d[i - 1][0]);
                d[i][1] = max(d[i - 1][0], d[i - 1][2]) + board[0][i]; //첫줄 붙임
                d[i][2] = max(d[i - 1][0], d[i - 1][1]) + board[1][i]; //둘째줄 붙임
            }

            cout &lt;&lt; max(max(d[n - 1][0], d[n - 1][1]), d[n - 1][2]) &lt;&lt; &quot;\n&quot;;
        }
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[FSM]]></title>
            <link>https://velog.io/@gb_leem/FSM</link>
            <guid>https://velog.io/@gb_leem/FSM</guid>
            <pubDate>Wed, 31 Jan 2024 15:57:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고
<a href="https://www.aleksandrhovhannisyan.com/blog/implementing-a-finite-state-machine-in-cpp/#what-is-a-finite-state-machine">https://www.aleksandrhovhannisyan.com/blog/implementing-a-finite-state-machine-in-cpp/#what-is-a-finite-state-machine</a>
<a href="https://gameprogrammingpatterns.com/state.html">https://gameprogrammingpatterns.com/state.html</a>
<a href="https://ansohxxn.github.io/design%20pattern/chapter11/">https://ansohxxn.github.io/design%20pattern/chapter11/</a>
<a href="https://docs.unrealengine.com/4.27/ko/AnimatingObjects/SkeletalMeshAnimation/StateMachines/Overview/">https://docs.unrealengine.com/4.27/ko/AnimatingObjects/SkeletalMeshAnimation/StateMachines/Overview/</a>
<a href="https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;blogId=jerrypoiu&amp;logNo=221235988023">https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;blogId=jerrypoiu&amp;logNo=221235988023</a></p>
</blockquote>
<h2 id="fsm-finite-state-machine">FSM (Finite State Machine)</h2>
<h3 id="1-fsm">1. FSM</h3>
<ul>
<li>다양한 상태들 간의 전이와 그에 따른 동작을 모델링하는 방식<ul>
<li>유한한 갯수의 상태들을 가지며, 상태들 중 하나의 상태만 취하는 상황</li>
<li>특정 조건이 되면 다른 상태로 변할 수 있어야 한다.</li>
</ul>
</li>
<li>FSM을 쓰는 이유<ul>
<li>가능한 상태들을 명확히 규정할 수 있다.</li>
<li>상태 중복을 피할 수 있다.</li>
<li>유지보수가 좋다.</li>
</ul>
</li>
<li>예시(캐릭터의 점프를 구현하기)
1) 특정 키를 눌러서 점프하는 코드를 작성했다.<pre><code>if(input == PRESS_B)
{
  Jump();
}</code></pre>2) 이단 점프를 막기 위해 bool 변수를 하나 도입해서 처리해준다.<pre><code>if(input == PRESS_B)
{
  if(!bIsJumping)
  {
       bIsJumping = true;
        Jump();
  }
}</code></pre>3) 아래 키보드를 누르면 엎드리고 떼면 일어서는 코드를 작성한다.<pre><code>if(input == PRESS_B) 
{
  if(!bIsJumping)
  {
       bIsJumping = true;
        Jump();
  }
} 
else if(input == PRESS_DOWN) 
{
  if(!isJumping_) 
  {
      Duck();
  }
}
else if(input == RELEASE_DOWN) 
{
  Stand();
}</code></pre>위처럼 하나의 기능이 추가될 때 마다 if 문이 늘어나고, 새로운 변수가 계속해서 늘어나게 된다는 문제점이 있다. </li>
<li><blockquote>
<p>FSM으로 이러한 문제를 해결</p>
</blockquote>
</li>
<li>간단한 방법으로는 FSM 상태를 enum class로 만들어서 switch case문으로 처리할 수 있다.</li>
<li>switch case도 코드가 꼬일 수 있기 때문에 <strong>상태를 별도의 클래스로 캡슐화한 다음 현재 상태를 나타내는 객체에게 행동을 위임하는 방식</strong>을 사용</li>
</ul>
<h3 id="2-fsm-코드">2. FSM 코드</h3>
<p><a href="https://www.aleksandrhovhannisyan.com/blog/implementing-a-finite-state-machine-in-cpp/#what-is-a-finite-state-machine">https://www.aleksandrhovhannisyan.com/blog/implementing-a-finite-state-machine-in-cpp/#what-is-a-finite-state-machine</a></p>
<pre><code>...</code></pre><h3 id="3-fsm-in-unreal-engine">3. FSM in Unreal Engine</h3>
<ul>
<li>State Machine<ul>
<li>언리얼 엔진에서 애니메이션을 위해 구현되어 있는 기능</li>
<li>Animation Bluprint를 만들어서 사용 가능하다.
<img src="https://velog.velcdn.com/images/gb_leem/post/2674fbfc-99eb-4a17-bc88-449a298d41d7/image.png" alt="">
<img src="https://velog.velcdn.com/images/gb_leem/post/ce2d9072-e8d5-4ec8-ac10-b39be002be85/image.png" alt=""></li>
</ul>
</li>
<li>위의 캐릭터 애니메이션 프로세스 흐름도를 아래의 state machine으로 구성할 수 있다.</li>
<li>구성 요소<ul>
<li><strong>State</strong><ul>
<li>캐릭터가 어떤 행동을 해야 할지에 대한 상태를 나타내기</li>
<li>해당 state를 더블클릭하면 output animation pose를 결정하도록 되어있다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/1a7ed4f0-677f-48a9-8421-c6ea2511a80e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/6d973fb9-3de6-4878-848d-954224e464cd/image.png" alt=""></p>
<ul>
<li><strong>Transition</strong><ul>
<li>한 상태에서 다른 상태로 전환함에 있어서 어떤 식으로 전환할지를 정하기</li>
<li>이때 transition rule에 따라 전환된다. </li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/dc2b17bc-f0fa-4ec5-b9ed-f7cfea0bb9db/image.png" alt=""></p>
<ul>
<li><strong>Conduit</strong><ul>
<li>transition은 한 상태에서 다른 상태로 일대일 대응관계이지만, conduit은 일대다, 다대다 대응이 가능하다.
<img src="https://velog.velcdn.com/images/gb_leem/post/3a48b150-cc84-4a22-b28e-73a94b0c9a03/image.png" alt=""></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[C++ 주요 컨테이너 정리]]></title>
            <link>https://velog.io/@gb_leem/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%A3%BC%EC%9A%94-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88</link>
            <guid>https://velog.io/@gb_leem/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%A3%BC%EC%9A%94-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88</guid>
            <pubDate>Tue, 30 Jan 2024 09:05:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고자료
배열 : <a href="https://learn.microsoft.com/ko-kr/cpp/cpp/arrays-cpp?view=msvc-170">https://learn.microsoft.com/ko-kr/cpp/cpp/arrays-cpp?view=msvc-170</a>
constexpr : <a href="https://learn.microsoft.com/ko-kr/cpp/cpp/constexpr-cpp?view=msvc-170">https://learn.microsoft.com/ko-kr/cpp/cpp/constexpr-cpp?view=msvc-170</a></p>
</blockquote>
<h2 id="1-array">1. Array</h2>
<h3 id="특징">특징</h3>
<ul>
<li>인접한 메모리 영역 차지<h3 id="생성-방식">생성 방식</h3>
</li>
<li>스택 선언<pre><code>constexpr size_t size = 1000;
double numbers[size]{ 0 };
numbers[0] = 1;
</code></pre></li>
</ul>
<p>for (size_t i = 1; i &lt; size; ++i)
{
    numbers[i] = numbers[i - 1] * 1.1;
}</p>
<p>for (const auto n : numbers)
{
    cout &lt;&lt; n &lt;&lt; &quot; &quot;; //1 1.1 1.21 1.331 ...
}</p>
<pre><code>* 힙 선언 (동적)</code></pre><p>size_t size2 = 100;
int* numbers2 = new int[size2] {0};
numbers2[0] = 1;</p>
<p>for (size_t i = 1; i &lt; size2; ++i)
{
    numbers2[i] = 100;
}
int* p = numbers2;</p>
<p>for (size_t i = 0; i &lt; size2; ++i)
{
    cout &lt;&lt; *(p++) &lt;&lt; &quot; &quot;; //100 100 100 100 ...
}</p>
<pre><code>* stl array -&gt; `#include &lt;array&gt;` 필요</code></pre><p>array&lt;int, 3&gt; a1;
a1[0] = 100;
a1[1] = 200;
a1[2] = 300;</p>
<pre><code>### 추가
* 함수에 배열 전달
  * 배열이 함수에 전달되면 첫번째 요소에 대한 포인터로 전달된다.
  * 예시)</code></pre><p>  int Sum(const int *num, const size_t len)
{
    int sum = 0;
    for (size_t i = 0; i &lt; len; ++i)
    {
        sum += num[i];
    }
    return sum;
}</p>
<pre><code>* `constexpr` 변수
  * 컴파일 시간에 초기화해야 한다.
  * 컴파일 도중에 &quot;반드시&quot; 값이 결정되도록 할 때 사용
  * 예시
  `constexpr float x = 42.0f;` -&gt; ok
  `constexpr int i;` -&gt; error (초기화 불가)
  `constexpr int k = i+1`
* `size_t`
  * 정의 :`typedef unsigned __int64 size_t;`
  * 64비트일 때 8바이트 unsigned int
  * 주로 배열 인덱싱 및 loop계산에 사용된다.
  -&gt; unsigned_int가 UINT_MAX를 초과하는 경우 예방?
## 2. Vector
### 특징
* 어떤 자료형도 넣을 수 있는 동적 배열
* 연속된 메모리 공간에 위치
* 자동 메모리 관리, 어떤 요소에도 임의 접근 가능

### 생성 방식
`std::vector&lt;int&gt; name1;`
`std::vector&lt;int&gt; name2(name1);` : 복사 생성자
`std::vector&lt;int&gt; name3(10);` : 0으로 값 초기화
* vector 생성 후에`reserve()` 써서 속도 빠르게 하는 것 좋다.

### 기본 함수
`push_back()` : 삽입
`pop_back()` : 삭제
`reserve()` : 공간 할당 하기
`capacity()` : **할당된** 요소의 공간 수
`size()` : 실제 들어있는 요소의 수
`insert(iterator, value)` : value를 특정 위치에 삽입
`erase(iterator)` : 특정 위치의 요소 삭제
`assign(num, value)` : vector를 value로 num 만큼 할당하기
`swap(vector)` : vector 교환하기
`resize()` : 
`clear()` : 모든 요소 제거, 크기 0이지만, 용량은 그대로

### 사용 예시</code></pre><p>#include <iostream>
#include <vector>
using namespace std;</p>
<p>int main()
{
    vector<int> vec1;
    vector<int> vec2; </p>
<pre><code>vec1.reserve(10);
vec1.push_back(10);
vec1.push_back(20);
vec1.push_back(30);

vec2.assign(11, 100);

//순차적으로 출력
for (vector&lt;int&gt;::const_iterator it = vec1.begin(); it != vec1.end(); ++it)
{
    cout &lt;&lt; *it &lt;&lt; endl; //10 20 30
}
cout &lt;&lt; &quot;\n&quot;;

//역으로 출력
for (vector&lt;int&gt;::reverse_iterator it = vec1.rbegin(); it != vec1.rend(); ++it)
{
    cout &lt;&lt; *it &lt;&lt; endl; //30 20 10
}
cout &lt;&lt; &quot;\n&quot;;

//vector 교환
vec1.swap(vec2);
for (vector&lt;int&gt;::const_iterator it = vec1.begin(); it != vec1.end(); ++it)
{
    cout &lt;&lt; *it &lt;&lt; endl; //100 100 100 100 100 100 100 100 100 100 100
}

//vector 지우기
vec1.clear();
cout &lt;&lt; vec1.size() &lt;&lt; &quot; &quot; &lt;&lt; vec1.capacity() &lt;&lt; endl; //0 11
cout &lt;&lt; &quot;\n&quot;;

//특정 위치 삽입
vector&lt;int&gt;::iterator iter = vec2.begin();
vec2.insert(iter + 1, 100);

for (vector&lt;int&gt;::const_iterator it = vec2.begin(); it != vec2.end(); ++it)
{
    cout &lt;&lt; *it &lt;&lt; endl; //10 100 20 30
}
cout &lt;&lt; &quot;\n&quot;;</code></pre><p>}</p>
<pre><code>### 추가
* 포인터 벡터

## 3. List
### 특징
* double linked list와 같은 구조
* 삽입과 제거 O(1), 메모리 연속으로 존재하지 않음
* 탐색이 느림, 임의 접근 불가능
### 사용 함수
`push_front()`
`push_back()`
### 사용 예시</code></pre><p>#include <list>
#include <iostream>
using namespace std;</p>
<p>int main()
{
    list<int> scores;
    scores.push_back(10);
    scores.push_back(20);
    scores.push_front(30);</p>
<pre><code>list&lt;int&gt;::const_iterator it = scores.begin();

for (; it != scores.end(); ++it)
{
    cout &lt;&lt; *it &lt;&lt; endl; //30 10 20
}</code></pre><p>}</p>
<pre><code>## 4. Map
### 특징
* key와 value의 쌍을 저장하는 자료구조
* key를 기준으로 정렬된다. -&gt; 이진 탐색 트리 기반
* 시간복잡도 O(logN) -&gt; 탐색 속도는 vector보다 빠르다.
* 만들면 자동으로 정렬된다.
* 해쉬맵이 아니다.
### 사용 함수
`insert()` : key와 value값 삽입
-&gt; 이미 있는 key 값을 insert 하면 false 반환한다.
`[]` operator : 참조 반환
-&gt; 없는 키를 쓰면 새 요소 삽입, 있는 키값이면 덮어쓰기  
`find()` : key값을 찾으면 해당 key 가지는 iterator 반환
`swap()` : 두 map의 key와 value 바꾸기
`clear()` : map 비우기
`erase()` : 한 요소 제거

### 사용 예시</code></pre><p>#include <map>
#include <string>
#include <iostream>
using namespace std;</p>
<p>int main()
{
    map&lt;string, int&gt; Scores;
    Scores.insert(pair&lt;string, int&gt;(&quot;A&quot;, 100));
    Scores.insert(pair&lt;string, int&gt;(&quot;B&quot;, 80));
    Scores.insert(pair&lt;string, int&gt;(&quot;C&quot;, 50));</p>
<pre><code>Scores.insert(pair&lt;string, int&gt;(&quot;C&quot;, 10)); //false
Scores[&quot;D&quot;] = 30;

cout &lt;&lt; Scores[&quot;A&quot;] &lt;&lt; endl; //100
cout &lt;&lt; Scores[&quot;C&quot;] &lt;&lt; endl; //50
cout &lt;&lt; Scores[&quot;D&quot;] &lt;&lt; endl; //30

//복사 생성자
map&lt;string, int&gt; copyScores(Scores);

for (map&lt;string, int&gt;::iterator it = copyScores.begin(); it != copyScores.end(); ++it)
{
    cout &lt;&lt; it-&gt;first &lt;&lt; &quot; &quot; &lt;&lt; it-&gt;second &lt;&lt; endl;
}

map&lt;string, int&gt;::iterator it = Scores.find(&quot;A&quot;);

if (it != Scores.end()) // 찾았을 때 -&gt; 못찾으면 end iterator 반환
{
    it-&gt;second = 99;
}
cout &lt;&lt; Scores[&quot;A&quot;] &lt;&lt; endl; //99

Scores.swap(copyScores);

cout &lt;&lt; copyScores[&quot;A&quot;] &lt;&lt; &quot; &quot; &lt;&lt; Scores[&quot;A&quot;] &lt;&lt; endl; //99 100</code></pre><p>}</p>
<pre><code>### 참고
* map에 내가 만든 class를 넣는 경우
  * 해당 class의 key를 비교하는 operator나 compare 함수를 구현해야함
* 사용 예시</code></pre><p>class Player
{
public:
    Player(int s,int i, string n)
        :Score(s)
        ,ID(i)
        ,Name(n)
    {
    }
    bool operator&lt;(const Player&amp; other)const //operator 구현
    {
        return this-&gt;getScores() &lt; other.getScores();
    }
    int getScores() const
    {
        return this-&gt;Score;
    }
    string getName() const
    {
        return this-&gt;Name;
    }
private:
    int Score;
    int ID;
    string Name;
};</p>
<p>class PlayerCompare //compare 함수 구현
{
public:
    bool operator() (const Player&amp; left, const Player&amp; right) const
    {
        return (left.getScores() &lt; right.getScores());
    }
};</p>
<p>int main()
{
    Player p1{ 100, 1, &quot;AAA&quot; };
    Player p2{ 50, 2, &quot;BBB&quot; };</p>
<pre><code>//operator 연산자                              
map&lt;Player, string&gt; test;
test.insert(pair&lt;Player, string&gt;(p1, &quot;aaa&quot;));
test.insert(pair&lt;Player, string&gt;(p2, &quot;bbb&quot;));

cout &lt;&lt; test[p1] &lt;&lt; &quot; &quot; &lt;&lt; test[p2] &lt;&lt; endl; // aaa bbb

//compare 함수
map&lt;Player, string, PlayerCompare&gt; test2;
test2.insert(pair&lt;Player, string&gt;(p1, &quot;aaa&quot;));
test2.insert(pair&lt;Player, string&gt;(p2, &quot;bbb&quot;));

for (map&lt;Player, string&gt;::iterator it = test2.begin(); it != test2.end(); ++it)
{
    cout &lt;&lt; it-&gt;first.getName() &lt;&lt; &quot;, &quot; &lt;&lt; it-&gt;second &lt;&lt; endl; //BBB bbb AAA aaa
}</code></pre><p>}</p>
<pre><code>## 5. Unordered_map
### 특징
* 정렬안된 map
* 해쉬로 구현되어서 일반 map 보다 빠르다.
* 특정값이 해쉬함수를 거쳐 index가 되고 bucket에 index를 통해 O(1)의 검색시간 가능하다.
  * 그러나 bucket 때문에 메모리 사용량은 증가
* 해쉬 함수는 충돌이 나지 않게 만드는 것이 중요하다.
* **해쉬 충돌이 생기지 않는 해쉬맵**
  * Closed Addressing (Chaining)
    * 충돌이 발생하면 같은 버킷에 여러 항목을 저장하는 방법
  * Open Addressing
    * 충돌이 발생하면 다른 빈 버킷을 찾는 방법
### 사용 예시</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Unreal Engine - Property Replication]]></title>
            <link>https://velog.io/@gb_leem/Unreal-Engine-Property-Replication</link>
            <guid>https://velog.io/@gb_leem/Unreal-Engine-Property-Replication</guid>
            <pubDate>Thu, 25 Jan 2024 16:25:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고
프로퍼티 리플리케이션 : <a href="https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Networking/Actors/Properties/">https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Networking/Actors/Properties/</a>
프로퍼티 지정자 : 
<a href="https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Properties/Specifiers/">https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Properties/Specifiers/</a>
조건식 리플리케이션 : 
<a href="https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Networking/Actors/Properties/Conditions/">https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Networking/Actors/Properties/Conditions/</a>
아키타입 : <a href="https://coding-hell.tistory.com/81">https://coding-hell.tistory.com/81</a>
언리얼 엔진 네트워킹 : 
<a href="https://docs.unrealengine.com/5.3/ko/networking-overview-for-unreal-engine/">https://docs.unrealengine.com/5.3/ko/networking-overview-for-unreal-engine/</a></p>
</blockquote>
<h2 id="프로퍼티-지정자">프로퍼티 지정자</h2>
<ul>
<li>엔진 및 에디터의 다양한 면에 대한 프로퍼티 작동방식을 지정하기 위해 UProperty 를 선언할 때 사용되는 키워드</li>
<li>사용 예시 1)<pre><code>UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = &quot;true&quot;))
class UWidgetComponent* OverheadWidget;</code></pre></li>
<li><blockquote>
<p>아키타입(내가 만든 블루프린트 클래스, c++클래스)과 인스턴스(bp와 c++ 클래스를 맵에 배치한 것) 둘 다 편집 가능</p>
</blockquote>
</li>
<li><blockquote>
<p>블루프린트에서는 수정 불가능</p>
</blockquote>
</li>
<li><blockquote>
<p>해당 변수는 클래스 내부에서만 접근 가능함</p>
</blockquote>
</li>
<li>사용 예시 2)<pre><code>UPROPERTY(ReplicatedUsing = OnRep_OverlappingWeapon)
class AWeapon* OverlappingWeapon;</code></pre></li>
<li><blockquote>
<p>네트워크 상에서 변수 값을 동기화 하는데, 해당 변수가 변경될 때 함수 <code>OnRep_OverlappingWeapon</code> 를 호출한다.</p>
</blockquote>
</li>
</ul>
<h2 id="프로퍼티-리플리케이션">프로퍼티 리플리케이션</h2>
<ul>
<li>서버는 replicate된 프로퍼티의 값이 변할 때 마다 각 클라이언트에 업데이트를 전송, 클라이언트는 액터의 로컬 버전에 적용</li>
<li>프로퍼티 구성
1) 헤더에 <code>UPROPERTY(replicated)</code> 사용
2) 액터 클래스 구현부에<code>GetLifetimeReplicatedProps</code> 함수 구현 필요</li>
<li><blockquote>
<p><code>DOREPLIFETIME(클래스 이름, 변수 이름);</code> 매크로 사용
3) 액터 생성자에 <code>bReplicates = true;</code> 설정</p>
</blockquote>
</li>
<li>결과로 리플리케이트로 지정된 값이 바뀐다면 나머지 클라이언트에도 다 바뀐걸로 적용된다.<h2 id="조건식-리플리케이션">조건식 리플리케이션</h2>
</li>
<li>프로퍼티가 리플리케이션에 등록되면 해제시킬 수 없기 때문에 가급적 많은 정보를 넣고 다수의 접속에서 공유하여 시간 절약을 할 수 있다.</li>
<li><code>DOPERPLIFETIME_CONDITION</code> 매크로 사용</li>
<li>사용 예시
<img src="https://velog.velcdn.com/images/gb_leem/post/cf223eab-39b4-42b2-8064-8db0e96fc6b0/image.PNG" alt=""></li>
<li>목표 (weapon에 닿았을 때 자신의 화면에서만 widget을 끄기/켜기 를 반복하기 위해서)
1) 위젯은 자신의 화면에서만 보고 싶다. simulated 에서는 보여줄 필요 없다.
2) 조건식 매크로에 <code>COND_OwnerOnly</code> 쓰면 pawn을 움직인 당사자의 화면과 서버에 변경된 점이 적용된다. 
3) 서버에서 안보이게 하기 위해서는 replicated 될 때만 바뀌게 만들었는데, 이렇게 되면 서버의 경우 위젯이 뜨지 않는다.</li>
<li>결과 영상
<a href="https://youtu.be/vspiWPZq5m0">https://youtu.be/vspiWPZq5m0</a></li>
</ul>
<h3 id="참고-property">참고) property</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[Unreal Engine - Delegate]]></title>
            <link>https://velog.io/@gb_leem/Unreal-Engine-Delegate</link>
            <guid>https://velog.io/@gb_leem/Unreal-Engine-Delegate</guid>
            <pubDate>Thu, 25 Jan 2024 13:28:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고 자료
델리게이트: <a href="https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/#%EB%8D%B8%EB%A6%AC%EA%B2%8C%EC%9D%B4%ED%8A%B8%EC%84%A0%EC%96%B8%ED%95%98%EA%B8%B0">https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/#%EB%8D%B8%EB%A6%AC%EA%B2%8C%EC%9D%B4%ED%8A%B8%EC%84%A0%EC%96%B8%ED%95%98%EA%B8%B0</a>
다이나믹 델리게이트 : <a href="https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/Dynamic/">https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/Dynamic/</a>
멀티캐스트 델리게이트 : <a href="https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/Multicast/">https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/Multicast/</a></p>
</blockquote>
<h2 id="델리게이트-delegate">델리게이트 (Delegate)</h2>
<h3 id="1-델리게이트란">1. 델리게이트란</h3>
<ul>
<li>C++ 오브젝트 상의 멤버 함수를 가리키고 실행시키는 데이터 유형</li>
<li>특징<ul>
<li>heap에 메모리 할당된다.</li>
<li>가급적 참조 전달 하기</li>
</ul>
</li>
<li>Delegate로..<ul>
<li>C++ 오브젝트 상의 멤버 함수 호출을 안전하게</li>
<li>임의 오브젝트의 멤버 함수에 동적으로 바인딩 &amp; 오브젝트에서 함수 호출 가능 (호출하는 곳에서 오브젝트의 유형 몰라도 된다<h3 id="2-델리게이트-선언하기">2. 델리게이트 선언하기</h3>
</li>
</ul>
</li>
<li>선언 매크로를 사용하여 선언한다.
<img src="https://velog.velcdn.com/images/gb_leem/post/1a9fc5b2-1601-4af3-a84c-8c75d2c6e730/image.PNG" alt=""><h3 id="3-델리게이트-바인딩하기">3. 델리게이트 바인딩하기</h3>
</li>
<li>UObject나 shared pointer 클래스 멤버에 바인딩 하는 경우 weak reference 유지 </li>
<li><blockquote>
<p>오브젝트가 소멸된 경우 <code>IsBound()</code> 함수를 통해 처리 가능
<img src="https://velog.velcdn.com/images/gb_leem/post/56afd089-13f3-45bf-8767-c6490a881198/image.PNG" alt=""></p>
</blockquote>
<h3 id="4-델리게이트-실행하기">4. 델리게이트 실행하기</h3>
</li>
<li>함수<ul>
<li><code>Execute()</code><ul>
<li>델리게이트에 바인딩 된 함수를 실행</li>
<li><strong>바인딩 되어있는지 체크하고 실행해야 한다!</strong></li>
<li><blockquote>
<p>초기화되지 않은 상태로 접근 가능한 반환값과 출력 파라메터가 델리게이터에 있을수 있기 때문</p>
</blockquote>
</li>
</ul>
</li>
<li><code>ExecuteIfBound()</code><ul>
<li>반환값이 없는 델리게이트 안전 체크</li>
</ul>
</li>
<li><code>IsBound()</code> <ul>
<li>델리게이트를 실행해도 안전한지 체크</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="5-dynamic-delegate">5. Dynamic Delegate</h3>
<ul>
<li><strong>Serialize 가능하며</strong>, 함수를 이름으로 찾을 수 있지만, 일반 델리게이트 보다는 느리다.</li>
<li>선언
<img src="https://velog.velcdn.com/images/gb_leem/post/9c6068c8-5040-4517-a051-80e8fe0dffc0/image.PNG" alt=""></li>
<li>바인딩
<img src="https://velog.velcdn.com/images/gb_leem/post/3b4aaa7e-8297-48f8-ba42-c7ee565d2e73/image.PNG" alt=""></li>
<li>실행 : 일반 델리게이트와 같다.</li>
</ul>
<h3 id="6-multicast-delegate">6. Multicast Delegate</h3>
<ul>
<li>여러 함수에 바인딩 시켜 실행시킬 수 있는 델리게이트</li>
<li>선언 : MULTICAST만 붙이면 된다.</li>
<li>바인딩
<img src="https://velog.velcdn.com/images/gb_leem/post/1faad57d-42fb-4ea2-8877-3918bd9c65e6/image.PNG" alt=""></li>
<li>실행<ul>
<li>여러 함수 델리게이트를 attach 한 다음 <code>Broadcast()</code> 함수를 통해 모두를 동시에 실행한다.</li>
<li>아무것도 바인딩 되어있지 않아도 문제없다. </li>
<li><blockquote>
<p>델리게이트를 사용하여 출력 변수를 초기화 시킬 때는 위험할 수 있다.</p>
</blockquote>
</li>
<li><code>Broadcast()</code> 호출 시 함수의 실행 순서는 정의되지 않는다.<h3 id="7-사용-예시">7. 사용 예시</h3>
</li>
</ul>
</li>
<li>커스텀 델리게이트
<img src="https://velog.velcdn.com/images/gb_leem/post/629c87e1-5c55-47ba-a78e-f2b9058c78b4/image.PNG" alt=""></li>
<li>선언
<img src="https://velog.velcdn.com/images/gb_leem/post/170deda0-aa7e-4065-b1ab-d7ee72bbfc2b/image.PNG" alt=""><ul>
<li><code>FOnCreteSessionComplete</code> 델리게이트 정의
<img src="https://velog.velcdn.com/images/gb_leem/post/f8b5633b-fc96-41e3-9b18-d83595615d41/image.PNG" alt=""></li>
</ul>
</li>
<li>바인딩
<img src="https://velog.velcdn.com/images/gb_leem/post/f5f89a0a-2a1d-44b0-94e8-9148e1864d9e/image.PNG" alt=""></li>
<li>사용 (멀티캐스트 델리게이트 이므로 <code>Broadcast()</code> 함수 사용)
<img src="https://velog.velcdn.com/images/gb_leem/post/9b564c22-272f-4bd0-bc52-30326c2f7504/image.PNG" alt=""></li>
</ul>
<h3 id="참고-serialization">(참고) Serialization</h3>
<blockquote>
<p>언리얼 오브젝트 처리 (UObject 시스템) : <a href="https://docs.unrealengine.com/4.26/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Objects/Optimizations/">https://docs.unrealengine.com/4.26/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Objects/Optimizations/</a></p>
</blockquote>
<ul>
<li>serialization란 언리얼 오브젝트를 한번에 안전하게 전달하는 것</li>
<li>다이나믹 델리게이트에서는 동적으로 메소드를 바인딩하기 때문에 serialization 특성이 필요하다.</li>
<li>다이나믹 델리게이트는 serialize 특징 덕분에 블루프린트에서 사용 가능하다??</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[컴퓨터 네트워크 7 : Wireless and Mobile Networks]]></title>
            <link>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-7-Wireless-and-Mobile-Networks</link>
            <guid>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-7-Wireless-and-Mobile-Networks</guid>
            <pubDate>Wed, 13 Dec 2023 07:31:09 GMT</pubDate>
            <description><![CDATA[<h2 id="1-introduction">1. Introduction</h2>
<ul>
<li><p>wireless network 구조
<img src="https://velog.velcdn.com/images/gb_leem/post/4e876463-ed76-434d-835f-297a21290be7/image.PNG" alt=""></p>
<ul>
<li>무선랜 access network<ul>
<li>AP(Access Point)가 존재</li>
<li>중계해주는 역할</li>
</ul>
</li>
<li>이동통신망 access network<ul>
<li>BS(Base Staion) 기지국 존재</li>
</ul>
</li>
</ul>
</li>
<li><p>wireless links 들의 특징
<img src="https://velog.velcdn.com/images/gb_leem/post/8917df4c-497c-4a9d-8015-94c10a9a7388/image.PNG" alt=""></p>
<ul>
<li>wifi는 범위는 좁지만 속도는 빠름</li>
<li>bluetooth는 범위도 좁고 속도도 느림</li>
<li>이동통신망은 범위가 넓다.</li>
</ul>
</li>
<li><p>wireless network의 동작 mode</p>
<ul>
<li>infrastructure mode<ul>
<li>공유기와 같은 인프라의 도움을 받아서 데이터를 주고받음</li>
</ul>
</li>
<li>ad hoc mode<ul>
<li>기지국과 같은 것이 존재하지 않음<h2 id="2-wireless">2. Wireless</h2>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>무선 네트워크의 특징</strong></p>
<ul>
<li>무선 링크의 에러 발생확률이 높다</li>
<li>사용자의 이동성이 크다</li>
</ul>
</li>
<li><p>이동통신망의 연결 동작 방식
<img src="https://velog.velcdn.com/images/gb_leem/post/37cd3108-b1b8-4ef0-a6b7-f48b655ecff5/image.PNG" alt=""></p>
<ul>
<li><strong>handoff</strong> : 하나의 cell에서 거리가 멀어저 BS와 연결이 끊어지면 다음으로 가까운 cell의 BS와 연결된다.<h3 id="2-1-wireless-links-and-network-characteristics">2-1. Wireless Links and network characteristics</h3>
</li>
</ul>
</li>
<li><p><strong>Wireless Link Characterisitics</strong></p>
<ul>
<li>신호 감소 (path loss)</li>
<li>다른 시스템의 영향을 받음 (interference)</li>
<li>sender가 방사형으로 신호를 전파함 -&gt; 이 특성으로 인해 receiver는 다양한 시간대의 data를 수신받아 원래의 모양과 다른 신호를 수신받게 된다.</li>
<li><strong>SNR이 클수록 좋은 신호!</strong><ul>
<li>SNR이 높다면 BER이 낮아진다. / SNR이 고정되어있다면 BER이 가장 작은 것을 선택하기</li>
<li>SNR (Signal to Noise Ratio)<ul>
<li>$SNR = \frac{S}{N}=\frac{신호전력}{잡음전력}$</li>
</ul>
</li>
<li>BER (Bit Error Rate)</li>
</ul>
</li>
<li><strong>Hidden Terminal Problem</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/7b0130e8-406f-4c13-82df-3d478328653a/image.PNG" alt=""><ul>
<li>CSMA 가정</li>
<li>A-&gt;B 전송함에 있어서 idle 상태이므로 전송을 함</li>
<li>C-&gt;D 전송함에 있어서 idle 이므로 전송을 하지만 C의 전송범위는 B까지 포함하기 때문에 C-&gt;D를 수행하는 순간 B에서 충돌이 발생한다.<h3 id="2-2-wifi-80211-wireless-lans">2-2. WiFi: 802.11 wireless LANs</h3>
</li>
</ul>
</li>
</ul>
</li>
<li><p>정의</p>
<ul>
<li>공식 무선랜 표준 </li>
<li>wifi라는 용어는 표준을 통과했을 때 주는 인증표시를 말한다.</li>
</ul>
</li>
<li><p>802.11 LAN 구조
<img src="https://velog.velcdn.com/images/gb_leem/post/a88ae8ae-faf4-47a7-9c8b-019e8aef9bc5/image.PNG" alt=""></p>
<ul>
<li>infrastructure 모드일때는 BS(=AP)의 도움을 받아 통신한다.</li>
<li>BSS(Basic Service Set)</li>
</ul>
</li>
<li><p>802.11: Channels, association</p>
<ul>
<li><p>AP의 admin이 사용할 수 있는 주파수를 선택하는 방식
-&gt; 채널을 scan 하고 beacon을 들으면서 AP를 선택함 (DHCP)</p>
</li>
<li><p><strong>scan의 방식</strong></p>
<ul>
<li><strong>passive</strong><ul>
<li>모바일 기기는 아무것도 하지 않음</li>
<li>각 주파수마다 beacon을 보내는지 아닌지 확인</li>
<li>연결이 필요할 때 request 보냄 (association request)</li>
<li>response 오면 연결 (association response)</li>
</ul>
</li>
<li><strong>active</strong><ul>
<li>AP가 있는지 probe request</li>
<li>probe response</li>
<li>association request</li>
<li>association response</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>802.11 다중접속</strong></p>
<ul>
<li><p><strong>CSMA/CA (2-frame)</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/98e7c60b-f935-4d8c-9703-63daa398327a/image.jpg" alt=""></p>
<ul>
<li>DIFS 동안 idle 인지 확인함</li>
<li>idle 이면 전송 시작</li>
<li>busy라면 끝날때 까지 기다림</li>
<li>DIFS 동안 idle인지 확인</li>
<li>idle 이면 backoff 실행-&gt;작은 backoff 한 station이 전송 시작
<img src="https://velog.velcdn.com/images/gb_leem/post/7621ca22-7f19-48a9-942d-921cdaea7a85/image.PNG" alt=""></li>
</ul>
</li>
<li><p><strong>RTS, CTS 방식(4-frame)</strong> -&gt; hidden terminal 방지
<img src="https://velog.velcdn.com/images/gb_leem/post/6509d8ff-7d09-4b7a-bffa-b4c5c6604e85/image.jpg" alt=""></p>
<ul>
<li>A-&gt;B 과정에서 RTS를 통해 A의 전송범위에 broadcast</li>
<li>B는 CTS 응답주면서 B의 전송범위에 broadcast</li>
<li>A-&gt;B data 전송 &amp; B-&gt;A ack 전송
<img src="https://velog.velcdn.com/images/gb_leem/post/c0183f21-ff64-48ad-bd90-b0eb3ec34c04/image.PNG" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>802.11 frame: addressing</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/09456026-d97b-4707-9891-fe76daa0b681/image.PNG" alt=""></p>
<ul>
<li>head에 주소가 4개인 이유는 아래 정보들를 담아야 하기 때문<ul>
<li>보내는 station의 주소</li>
<li>AP의 주소</li>
<li>도착지 station의 주소</li>
<li>ad hoc mode를 위한 주소</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>802.11: mobility within same subnet</strong></p>
<ul>
<li>한 subnet 아래 bss에서는 이동해도 커버가 가능하다. (작은 범위의 이동성)</li>
<li>bss1-&gt;bss2로 이동하는 것은 이동할 때마다 association을 하기 때문에 해당 기기가 이동했는지 알 수 있다.</li>
</ul>
</li>
<li><p><strong>802.11: advanced capabilities</strong></p>
<ul>
<li><strong>rate adaptation</strong> <ul>
<li>와이파이의 연결상태가 좋으면 고속으로 전송하고 그렇지 않다면 저속으로 전송하는 시스템</li>
<li>자동으로 해줌, 저속으로 전송하는 이유는 bit error를 줄이기 위해서</li>
</ul>
</li>
<li><strong>power management</strong><ul>
<li>베터리에 의존하기 때문에 power관리를 해야함!</li>
<li>node to AP : node가 자신은 sleep 할거라고 AP에게 알려주어서 해당 node에게 전송할 필요 없게 되어 power를 save한다.</li>
<li>beacon frame : AP가 보낸 list를 확인해서 자신이 받을 packet이 없다면 해당 기기는 쉬기</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[컴퓨터 네트워크 6: The Link Layer and LANs]]></title>
            <link>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-6-The-Link-Layer-and-LANs</link>
            <guid>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-6-The-Link-Layer-and-LANs</guid>
            <pubDate>Tue, 12 Dec 2023 18:56:57 GMT</pubDate>
            <description><![CDATA[<h2 id="1-introduction">1. Introduction</h2>
<ul>
<li>용어<ul>
<li>node : host &amp; router </li>
<li>frame : 2계층에서 packet을 부르는 말</li>
<li><strong>link</strong> : source에서 destination을 가는 동안 존재하는 경로에서 router와 host를 연결하는 것들을 말한다.</li>
</ul>
</li>
<li><strong>link layer이 제공하는 services</strong><ul>
<li>framing, link access<ul>
<li>channel access : 경쟁을 통해 channel 확보하기</li>
<li>MAC 주소 : 2계층만의 고유한 주소값, 시작점과 도착지의 정보</li>
</ul>
</li>
<li>flow control </li>
<li>error detection</li>
<li>error correction</li>
<li>half duplex and full duplex</li>
</ul>
</li>
<li>link layer는 <strong>NIC(Network Interface Card)</strong> 에 구현되어있다.<h2 id="2-error-detection-correction">2. Error detection, correction</h2>
</li>
<li><strong>Error detection</strong><ul>
<li>EDC : error detection과 correction을 하는 bits</li>
</ul>
</li>
<li><strong>Parity Checking</strong><ul>
<li>single bit parity <ul>
<li>짝수나 홀수 패리티 방식을 통해 1의 갯수를 측정하여 error를 찾아낸다</li>
<li>그러나 한번에 한개의 비트가 아닌 여러개의 비트 error가 생긴 경우 문제를 해결하지 못한다.</li>
</ul>
</li>
<li>two-dimensional bit parity<ul>
<li>행과 열 두개로 패리티를 구성하여 두 번의 체크를 통해 error를 찾아낸다.</li>
</ul>
</li>
</ul>
</li>
<li><strong>CRC(Cyclic Redundancy Check)</strong><ul>
<li>용어<ul>
<li>D는 data bit</li>
<li>R은 CRC bit, 크기는 r bits</li>
<li>G는 bit pattern(generator), r+1 bits</li>
</ul>
</li>
<li>구조
<img src="https://velog.velcdn.com/images/gb_leem/post/7f6591d0-bd2e-499b-9891-9786d6b632a7/image.PNG" alt=""></li>
<li>계산<ul>
<li>$\frac{&lt;D,R&gt;}{G}$ 의 결과가 나머지가 없어야 error가 없다고 판별!</li>
<li>$&lt;D,R&gt; = D*2^r$ XOR $R$<ul>
<li>이때 $D*2^r$은 r비트만큼 왼쪽으로 shift 하는 결과</li>
</ul>
</li>
<li><strong>결론적으로 우리가 구하는 것은 R이고 $\frac{D*2^r}{G}$의 나머지가 $R$이다.</strong></li>
</ul>
</li>
<li>예시<ul>
<li>D=[101110], G=[1001], r=3(G의 크기로부터 알수있음)</li>
<li>$R = \frac{D*2^r}{G}$의 나머지<ul>
<li>$D*2^3 = 101110 000$</li>
<li>$\frac{D*2^r}{G}=$ 몫: 101011 나머지: 011</li>
<li>101110 011 은 1001로 나눠떨어지게 된다.<h2 id="3-multiple-access-protocols">3. Multiple access protocols</h2>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>2계층 프로토콜의 핵심 기능 중 하나</strong><ul>
<li>link의 두가지 타입<ul>
<li>point to point : one server one receiver</li>
<li>broadcast</li>
</ul>
</li>
</ul>
</li>
<li>그렇다면 하나의 공유하는 broadcast channel을 어떻게 분배할 것인가! (channel의 사용권 결정하기)<ul>
<li>이상적인 경우<ul>
<li>MAC(Multiple Access Channel) of rate Rbps</li>
<li>M개의 노드가 있다면,,, R/M으로 나누기</li>
<li>완전히 분산된 시스템이다. 동기화나 정지하는 마스터 노드가 없다. 단순하다는 장점은 있다.</li>
</ul>
</li>
</ul>
</li>
<li><strong>MAC protocol의 종류</strong><ul>
<li>channel partitioning<ul>
<li>채널을 작은 조각들로 나누기</li>
<li>안쓰는데 1/M으로 나눠진 것들은 낭비가 된다.</li>
</ul>
</li>
<li>random access<ul>
<li>사용권을 경쟁을 통해 획득</li>
<li>가장 많이 쓰는 방식</li>
</ul>
</li>
<li>taking turns<ul>
<li>경쟁없이 돌아가면서 쓰는 방식</li>
</ul>
</li>
</ul>
</li>
<li><strong>Channel Partitioning MAC Protocols</strong><ul>
<li>TDMA<ul>
<li>시간을 1/N으로 나누기</li>
<li>각 frame을 고정된 길이로 나눈다.</li>
</ul>
</li>
<li>FDMA<ul>
<li>대역폭을 1/N으로 나누기</li>
</ul>
</li>
</ul>
</li>
<li><strong>Random Access Protocol</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/1a029835-8aab-4faf-bfc8-4754978e6aba/image.jpg" alt=""><ul>
<li>전송 노드는 항상 최대 전송률인 Rbps로 전송</li>
<li>만약 충돌이 발생하면 랜덤한 시간동안 기다린 후 재전송을 진행한다.</li>
<li><strong>Slotted ALOHA</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/18f739b8-027d-4770-a833-2718ceb8fa5f/image.jpg" alt=""><ul>
<li>전제조건<ul>
<li>모든 frame은 같은 크기</li>
<li>충돌이 발생하면, 성공할 때 까지 p의 확률로 재전송<ul>
<li>이때 확률 p로 재전송 하는것은 확률이 매우 치우친 동전던지기를 하는 것과 같다.</li>
</ul>
</li>
</ul>
</li>
<li>특징<ul>
<li>장점 : 매우 분산적이며, 간단하다.</li>
<li>단점 : 충돌이 발생하고, slot이 낭비된다. 충돌이 발생해도 해당 slot의 전송을 끊지 않고 계속 보냄    </li>
</ul>
</li>
<li>효율성<ul>
<li>임의의 한 노드가 성공적으로 보낼 확률 : $Np(1-p)^{N-1}$</li>
<li>최대 효율은 1/e = .37 (37%)</li>
<li><strong>충돌이 발생하지 않으려면, 전송 시작 전 slot에서 전송하려는 데이터 이외의 데이터가 발생하지 않으면 충돌이 발생하지 않는다.</strong></li>
</ul>
</li>
</ul>
</li>
<li><strong>Pure ALOHA</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/96718672-9334-45ea-915b-2f87cd3b19be/image.PNG" alt=""><ul>
<li>slot을 사용하지 않는 알로하, 동기화 작업 안함 -&gt; 충돌이 더 많아진다는 문제점이 있다.</li>
<li><strong>pure 알로하가 충돌이 발생하지 않으려면 
1) data A가 전송하는데 걸리는 시간 T만큼 이전 기간동안 데이터가 발생하면 안된다.
2) data A를 전송하는 시간 T 동안 다른 데이터가 발생하면 안된다.</strong></li>
<li>효율성<ul>
<li>최대 효율이 18%</li>
</ul>
</li>
</ul>
</li>
<li><strong>CSMA(Carrier Sense multiple Access)</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/1d482688-04eb-477f-a3a2-9174c37ac54c/image.PNG" alt=""><ul>
<li>channel을 쓰고 있는지 아닌지를 확인<ul>
<li>안쓰고 있다면(idle) 바로 데이터 전송      </li>
<li>쓰고 있다면(busy) 종료될 때 까지 대기</li>
</ul>
</li>
<li>이 방식은 충돌을 피하는 것은 불가능하다.<ul>
<li>propagation delay가 길어지면(node와 node 사이가 멀어지면) 충돌 발생 가능성이 더욱 높아진다. -&gt; 그래프의 기울기가 완만해 지는 것</li>
<li>충돌이 발생하면 다른 node들이 전송을 할 수 없어서 낭비된다.</li>
</ul>
</li>
</ul>
</li>
<li><strong>CSMA/CD(CSMA with Collision Detection)</strong><ul>
<li>이더넷에서 쓰는 방식</li>
<li>충돌이 검출되면 전송을 끊어버림</li>
<li>알고리즘
1) network layer에서 datagram 가져와서 frame 만들기
2) Idle인지 busy인지 carrier sensing 수행
3) 전체에서 충돌 없다면 frame 보내고 종료
4) 다른 전송을 확인한 경우 -&gt; abort<ul>
<li>abort된 경우 <strong>binary exponential backoff 수행</strong> </li>
<li>m번의 collision 발생한 경우 -&gt; K를 ${0,1,2,...,2^{m-1}}$에서 K를 선택</li>
<li>NIC는 K*512 bit time을 기다린 후 2)로 돌아감 <ul>
<li>if) R = 100Mbps -&gt; 1 bit time = $10^{-8}sec$</li>
</ul>
</li>
<li>많은 충돌이 발생할수록 집합의 크기가 지수적으로 커짐</li>
</ul>
</li>
<li>효율성<ul>
<li>$efficieny = \frac{1}{1+5\frac{t_{prop}}{t_{trans}}}$</li>
<li>propagation delay가 0일수록, transmit max-size frame 시간이 무한대에 가까울수록 효율성이 1과 가까워짐</li>
<li><strong>결론은 ALOHA보다 성능이 좋다</strong></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>Taking turns</strong><ul>
<li>polling<ul>
<li>중앙집중형, 마스터 노드가 RR 방식으로 polling 수행
-&gt; master 노드가 다른 노드들에게 최대로 보낼 수 있는 프레임을 알려줌</li>
<li>오버헤드, 한번에 다 고장난다는 문제점 있다.</li>
</ul>
</li>
<li>token passing<ul>
<li>token이라는 짧은 제어 message를 사용하는 방식</li>
<li>즉 전송중인 노드는 token을 가지고 있는 방식</li>
<li>그러나 token이 문제가 생길 수 있다는 단점이 있다.<h2 id="4-lans">4. LANs</h2>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>IP address</strong><ul>
<li>network layer의 주소이다. 32bit, ex) 128.119.40.136</li>
<li>3계층의 forwarding을 위해 사용</li>
<li>위치에 따라 주소가 달라짐</li>
</ul>
</li>
<li><strong>MAC address</strong><ul>
<li>link layer의 주소이다. 48 bit, ex) 1A-2F-BB-76-09-AD</li>
<li>물리적으로 연결된 다른 인터페이스의 frame을 가져옴</li>
<li>어뎁터의 MAC 주소는 위치에 따라 바뀌지 않음!!<h3 id="4-1-arp-address-resolution-protocol">4-1. ARP (Address Resolution Protocol)</h3>
</li>
</ul>
</li>
<li>정의: IP주소와 MAC주소를 변환해주는 역할<ul>
<li>ARP table : IP주소, MAC 주소, TTL 순서로 작성된다.<ul>
<li>TTL(time to live): 대체로 20분으로 설정, 20분 동안 address mapping이 이루어지지 않으면 table에서 지워진다.</li>
</ul>
</li>
</ul>
</li>
<li><strong>ARP protocol (A와 B가 같은 subnet에 존재)</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/69c4f284-84f4-4e9a-bdea-d6f8f1a7687c/image.PNG" alt=""><ul>
<li>ARP table 비어있을 때 (A 기준)<ul>
<li>도착지 MAC 주소: FF-FF-FF-FF-FF-FF (전체에게 보낸다는 의미)</li>
<li>만약 B가 해당 query에 응답한다면 MAC 주소를 다시 보냄</li>
<li>ARP table에 B의 IP 주소와 MAC addr, TTL을 적는다.</li>
</ul>
</li>
</ul>
</li>
<li><strong>ARP protocol (A와 B가 다른 subnet에 존재)</strong><ul>
<li>R이라는 라우터를 통해 B로 이동한다.
<img src="https://velog.velcdn.com/images/gb_leem/post/d3392b2b-c2d9-4119-9edb-f785d693e117/image.PNG" alt=""></li>
<li>A의 목적지 MAC주소는 R의 인터페이스 MAC주소이고 목적지 IP 주소는 B의 IP 주소이다.</li>
<li>이후 subnet과 subnet 간의 이동은 link layer의 역할이 아니다.
<img src="https://velog.velcdn.com/images/gb_leem/post/19c0f774-5fd0-4fe0-8b1d-1708076e0040/image.PNG" alt=""></li>
<li>다시 R의 전송 시작 주소는 R의 MAC주소이고 도착지 주소는 B의 MAC주소가 되어 A-&gt;R-&gt;B로 전달된다. IP 주소는 그대로<h3 id="4-2-ethernet">4-2. Ethernet</h3>
</li>
</ul>
</li>
<li>선으로 연결된 근거리 통신망, 싸고 단편하다.</li>
<li>topology<ul>
<li>이전에는 bus방식 썼지만, 충돌이 발생해서 <strong>switched</strong> 방식으로 바뀜</li>
</ul>
</li>
<li>frame structure
<img src="https://velog.velcdn.com/images/gb_leem/post/600b1b4e-7af6-4788-8f95-b046c593e700/image.PNG" alt=""><ul>
<li>preamble: 동기화, 신호의 시작 알려주기</li>
<li>address: MAC 주소의 도착지</li>
<li>type: 2-&gt;3계층으로 옮기기 위한 protocol</li>
<li>CRC: error 검출</li>
</ul>
</li>
<li>특징<ul>
<li>connectionless</li>
<li>unreliable : 안정적인 전송 불가능</li>
<li>CSMA/CD 사용<h3 id="4-3-switch">4-3. Switch</h3>
</li>
</ul>
</li>
<li>이더넷의 스위치는 스스로 알아서 동작함<ul>
<li>transparent</li>
<li>plug and play, self learning</li>
</ul>
</li>
<li>multiple simultaneous transmission
<img src="https://velog.velcdn.com/images/gb_leem/post/b99e1c1a-6090-4d27-add5-fa4a11a2c514/image.PNG" alt=""><ul>
<li>host들은 스위치와 전용 direct 연결로 구성</li>
<li>collision 발생 안함 -&gt; 각 경로가 full duplex이므로<ul>
<li>A-&gt;A&#39; B-&gt;B&#39;은 동시에 일어날 수 있고 충돌도 안생김</li>
<li>그러나 A-&gt;A&#39;과 B-&gt;A&#39;이라는 전송이 동시에 이루어지면 충돌 발생</li>
</ul>
</li>
</ul>
</li>
<li><strong>self learning</strong><ul>
<li>cf) IP의 forwarding table은 라우팅 프로토콜로 구성되며, 양이 매우 많다..(self learning 불가능)</li>
<li>MAC 주소는 IP에 비해 간단하므로 self learning이 가능하다.
<img src="https://velog.velcdn.com/images/gb_leem/post/adff6949-0404-45b0-a6e3-a265932c1055/image.PNG" alt=""><ul>
<li>위의 그림처럼 A-&gt;A&#39;를 지나간다면, 테이블을 채우고 다음 것을 진행하면서 테이블을 모두 채운다. (TTL : time to live 데이터의 유효기간)</li>
<li>만약 drop time때까지 도착지에 도착을 못하면 drop 해버림</li>
</ul>
</li>
</ul>
</li>
<li>스위치와 라우터의 차이점<ul>
<li>스위치<ul>
<li>link layer 장치이며, store-and-forward 진행</li>
<li>flooding, learning, MAC 주소를 통해 forwarding table을 만든다.</li>
</ul>
</li>
<li>라우터<ul>
<li>network layer 장치이며 store-and-forward 진행</li>
<li>라우팅 알고리즘을 통해 table 계산, IP 주소이용<h2 id="a-day-in-the-life-of-a-web-request">A Day in the life of a web request</h2>
</li>
</ul>
</li>
</ul>
</li>
<li>참고 유튜브
<a href="https://www.youtube.com/watch?v=paT7cVt-ySQ">https://www.youtube.com/watch?v=paT7cVt-ySQ</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[컴퓨터 네트워크 5: Network Layer - Control Plane]]></title>
            <link>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-5-Network-Layer-Control-Plane</link>
            <guid>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-5-Network-Layer-Control-Plane</guid>
            <pubDate>Mon, 11 Dec 2023 17:09:21 GMT</pubDate>
            <description><![CDATA[<h2 id="1-introduction">1. Introduction</h2>
<ul>
<li>Network-layer functions (Recap)<ul>
<li>forwarding: data plane / 라우터 안에서 </li>
<li>routing: control plane / 전체 경로상에서</li>
</ul>
</li>
<li>Per-router control plane<ul>
<li>기존에 쓰던 방식</li>
<li>각 라우터당 라우팅 알고리즘 존재</li>
</ul>
</li>
<li>Software-Defined Networking control plane<ul>
<li>중앙 집중형</li>
<li>agent가 server에 존재<h2 id="2-routing-protocols">2. Routing Protocols</h2>
</li>
</ul>
</li>
<li><strong>출발지에서 목적지까지 &quot;good&quot; &quot;path&quot;를 결정하기</strong><ul>
<li>path <ul>
<li>router packet의 sequence</li>
<li>initial source에서 destination host까지의 경로</li>
</ul>
</li>
<li><strong>good</strong> : 적은 cost (빠름, 혼잡x)</li>
</ul>
</li>
<li>Graph abstraction: link costs<ul>
<li>$cost = \frac{1}{bandwidth}$ or   $cost = \frac{1}{congestion}$</li>
<li>각 링크 당 가중치를 cost로 생각하고 그래프 문제를 푼다.<ul>
<li>가중치가 무한대라면 직접 연결이 안된 경우</li>
</ul>
</li>
</ul>
</li>
<li>Routing Algorithm Classification
<img src="https://velog.velcdn.com/images/gb_leem/post/3f6edd8e-e8e2-4319-a43a-a6246243adbe/image.PNG" alt=""><h3 id="2-1-link-state">2-1. Link State</h3>
</li>
<li><strong>다익스트라 link-state 라우팅 알고리즘</strong><ul>
<li>특징<ul>
<li>centralized</li>
<li>iterative</li>
</ul>
</li>
<li>notation<ul>
<li>$C_{x,y}$ : x,y를 직접 연결한 link의 가중치</li>
<li>$D(v)$ : 목적지 v까지의 최소 비용</li>
<li>$p(v)$ : 목적지까지 가는길에 바로 직전의 노드</li>
<li>$N&#39;$ : 최소비용경로가 알려진 노드</li>
</ul>
</li>
<li>알고리즘<ul>
<li>$N&#39;$에 자기 자신(시작) 노드를 넣고 시작해서 최소 비용인 노드들을 하나씩 넣다가 모든 노드가 $N&#39;$에 들어가면 반복을 종료한다.</li>
</ul>
</li>
<li>목적지까지의 최소 비용 계산식<ul>
<li>$D(v) = min(D(v), D(w)+C_{w,v})$<ul>
<li>$D(v)$ : 기존값</li>
<li>$D(w)+C_{x,y}$ : 새로 비교하게 되는 값</li>
</ul>
</li>
</ul>
</li>
<li>분석<ul>
<li>알고리즘 시간 복잡도<ul>
<li>n개의 노드가 있을때 $O(n^2)$</li>
<li>$O(nlgn)$으로도 구현 가능</li>
</ul>
</li>
<li>message 복잡도<ul>
<li>각 노드가 연결된 모든 노드에 정보를 전달해야함 </li>
<li>$O(n^2)$</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Oscillations Possible<ul>
<li>네비게이션의 경로 추천 기능 처럼..</li>
<li>A경로가 빠를 때 A경로를 추천하지만, 점차 A경로가 포화상태가 되고 이후로는 B경로를 추천하게된다.<h3 id="2-2-distance-vector">2-2. Distance Vector</h3>
</li>
</ul>
</li>
<li><strong>Bellman-Ford equation (DP)</strong><ul>
<li>$D_x(y)=min_v{c_{x,y}+D_v(y)}$</li>
</ul>
</li>
<li>BF Example
<img src="https://velog.velcdn.com/images/gb_leem/post/73784838-0299-430d-b1ca-19bc087e8dbc/image.PNG" alt=""></li>
<li><strong>Distance vector algorithm</strong><ul>
<li>다른 노드가 계산된 결과를 바탕으로 계속해서 업데이트하기 (다익스트라 알고리즘은 다른 노드의 정보 생각x)</li>
<li><strong>&quot;good news travels fast&quot;</strong> : 더 좋은 값으로 바뀐 것은 더 빨리 다른 노드들로 전파된다.</li>
<li>&quot;bad news travels slow&quot; : count to infinity<h3 id="2-3-comparison-of-ls-and-dv">2-3. Comparison of LS and DV</h3>
</li>
</ul>
</li>
<li>message complexity<ul>
<li>LS : n개의 라우터 -&gt; $O(n^2)$</li>
<li>DV : 수에 따라 달라짐</li>
</ul>
</li>
<li>speed of convergence<ul>
<li>LS : global, $O(n^2)$</li>
<li>DV : distributed and iterative (LS보다 오래걸림)</li>
</ul>
</li>
<li>robustness<ul>
<li>LS</li>
<li>DV : 잘못된 정보 한번에 모두가 잘못될 수 있다. (LS보다 보안이 취약함)<h2 id="3-intra-isp-routing-ospf">3. Intra-ISP routing: OSPF</h2>
</li>
</ul>
</li>
<li>making routing scalable<ul>
<li>이전까지는 라우터가 모두 동일한 것으로 생각했지만 실생활에서는 그렇지 않다.</li>
<li>실제로는 모든 라우터들의 도착지를 테이블에 저장할 수 없으며, 각 ISP는 네트워크를 자신이 원하는 대로 운영하고 싶어한다. 이런 것들을 위해 <strong>&quot;autonomous systems</strong> 으로 조직화 해서 운영한다!<h4 id="autonomous-systems-aka-domains"><strong>Autonomous Systems (aka domains)</strong></h4>
</li>
<li><strong>Intra-AS</strong> <ul>
<li>AS 내부의 동작</li>
<li>AS 내부에서는 같은 프로토콜로 동작한다.</li>
<li>gateway router 라는 다른 AS와 연결되는 link가 존재한다.</li>
</ul>
</li>
<li><strong>Inter-AS</strong><ul>
<li>AS와 AS간의 동작</li>
<li>특정 AS에서 나가는 datagram이 있을때 어떤 라우터를 골라야 하는지는 <strong>연결된 AS를 보고 어디로 갈 수 있는지를 확인해 본 후 결정한다.</strong></li>
</ul>
</li>
</ul>
</li>
<li><strong>Intra-AS routing</strong><ul>
<li>RIP(Routing Information Protocol)<ul>
<li>classic DV 방식, 잘 안씀</li>
</ul>
</li>
<li>EIGRP(Enhanced Interior Gateway Routing Protocol)<ul>
<li>DV based</li>
</ul>
</li>
<li><strong>OSPF(Open Shortest Path First)</strong><ul>
<li>Link-State 라우팅</li>
<li>IS-IS protocol(OSPF와 유사)<h4 id="ospf-routing">OSPF routing</h4>
</li>
</ul>
</li>
</ul>
</li>
<li>특징<ul>
<li>라우팅 동작 방식이 공개되어있다.</li>
<li>classic link-state 방식으로 동작함<ul>
<li>링크 상태 flooding, 인접한 것 뿐만 아니라 모든 라우터에게 정보를 broadcasting</li>
</ul>
</li>
<li>multiple link cost metrics : 동일한 비용을 가진 다른 링크를 이용할 수 있다. (분산시키기)</li>
<li>security : 모든 메세지를 인증을 통해 참여한다.</li>
<li>two-level hierarchy<ul>
<li>backbone(inter AS 담당)-&gt;border(gateway 역할)-&gt;local 라우터</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="4-routing-among-isps-bgp">4. Routing Among ISPs: BGP</h2>
<ul>
<li>Inter-AS routing 방식이기 때문에 전 세계에 하나만 존재한다. </li>
<li><strong>BGP(Border Gateway Protocol)</strong><ul>
<li>라우터의 forwarding table의 목적지가 AS 외부에 있는 경우 필요한 프로토콜</li>
<li><strong>eBGP(external BGP)</strong><ul>
<li>AS와 AS를 연결하는 BGP </li>
</ul>
</li>
<li><strong>iBGP(internal BGP)</strong><ul>
<li>같은 AS 내의 라우터 간 BGP 연결 </li>
<li><strong>iBGP가 필요한 이유</strong>는 바깥에서 받아온 정보를 내부에 알려주기 위해서 이다</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/381a20bc-da85-43ab-9ac8-a3d9a8fb2b6b/image.PNG" alt=""></p>
<ul>
<li>BGP basics<ul>
<li>BGP session<ul>
<li>두개의 BGP 라우터끼리는 반영구적인 TCP를 통해 연결한다.</li>
</ul>
</li>
<li>동작 예시
1) 위의 그림에서 AS3에서 x라는 데이터를 AS2에게 보내면 AS3, x라고 표시한다. 
2) 이후 AS2는 AS1으로 전달하면서 x는 AS2를 거쳐 AS3로부터 왔다는 뜻으로 AS2,AS3,x 라고 표시한다. </li>
</ul>
</li>
<li>경로 특성<ul>
<li>prefix(목적지) + attributes(특성)의 형태로 전달</li>
<li><strong>policy-based</strong><ul>
<li>use import policy</li>
</ul>
</li>
<li>특성의 종류<ul>
<li>AS-PATH : 목적지 주소에 대한 배포가 어떤 주소를 거쳐서 왔는지</li>
<li>NEXT-HOP : AS-PATH를 시작하는 라우터 인터페이스의 IP 주소</li>
</ul>
</li>
</ul>
</li>
<li>BGP advertisement
<img src="https://velog.velcdn.com/images/gb_leem/post/931ddac4-225d-4ae9-a122-747e6feaf67e/image.PNG" alt=""></li>
<li>BGP message<ul>
<li>OPEN</li>
<li>UPDATE</li>
<li>KEEPALIVE</li>
<li>NOTIFICATION</li>
</ul>
</li>
<li><strong>BGP path advertisement??</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/be54fc06-44a5-4f8b-9260-2577a1185350/image.PNG" alt=""></li>
<li>Intra vs Inter AS<ul>
<li>policy : inter AS의 경우 관리자가 라우팅되는 방법이나 누가 라우팅 하는지 등을 제어한다. intra AS는 단일 관리자이므로 정책이 의미 없다</li>
<li>scale : 계층 라우팅을 통해 사이즈와 트래픽을 줄인다.</li>
<li>performance : intra AS가 성능에 더욱 focus</li>
</ul>
</li>
<li>Hot potato routing<ul>
<li>domain 내에서 비용이 가장 적은 local gateway를 선택하기</li>
<li>AS 바깥의 비용은 생각하지 않고 빨리 자신의 AS내에서 밖으로 보내는 것</li>
</ul>
</li>
<li><strong>BGP: achieving policy via advertisements</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/db5f88b3-57cf-44e9-9aa1-a98d33c4bc16/image.PNG" alt=""><ul>
<li>다른 ISP간의 transit traffic을 전달하지 않기 (X가 B와 C간의 트래픽을 전달하는 것을 막는 것이 목적)</li>
<li>X가 자신을 제외하고 다른 경로가 없다고 알려주어서 B에서 C의 경로를 막는다.</li>
</ul>
</li>
<li><strong>BGP route selection</strong>
1) policy 따르기!, 지역 선호도
2) 짧은 AS-PATH
3) 가까운 NEXT-HOP, 뜨거운 감자
4) 다른 기준들<h2 id="5-sdn-control-plane">5. SDN control plane</h2>
</li>
<li>왜 control plane을 centralized 했을까<ul>
<li>network mangement를 쉽게 하기</li>
<li>programming이 쉽다.</li>
<li>open 해서 기술의 발전을 도모</li>
</ul>
</li>
<li><strong>Traffic engineering</strong><ul>
<li>과거의 방식<ul>
<li>가중치를 분산시키기 위해 source에서 destination 까지의 경로를 다양하게 구성하는 것이 어렵다.</li>
<li>load balancing 구현 어렵다.</li>
<li>특정 지점을 지나서 가는 경로를 만들도록 구현하기가 어렵다.</li>
</ul>
</li>
<li><strong>SDN</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/9a5da326-912d-447c-b2e7-141da6db9a30/image.PNG" alt=""><ul>
<li>과거의 방식에서 불가능한 것을 할 수 있게 되었다.</li>
<li>SDN은 hardware/controller/application 세가지로 분류하여 동작한다.<ul>
<li><strong>dataplane switches</strong><ul>
<li>hardware에 구현된 dataplane forwarding을 위한 switch</li>
<li>openflow를 통해 control plane과 정보를 주고받음</li>
</ul>
</li>
<li><strong>software controller(network OS)</strong><ul>
<li>network의 상태 체크하는 역할</li>
<li>sounthbound API를 통해 switch들과 상호작용하며, northbound API를 통해 application들과 상호작용한다.</li>
</ul>
</li>
<li><strong>network-control apps</strong><ul>
<li>unbundled 한 특성 (각각 하는 기능이 따로 나누어져 있다)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>OpenFlow protocol</strong><ul>
<li>세가지 메세지 종류<ul>
<li>controller to switch</li>
<li>asynchronous (switch to controller)</li>
<li>symmetric</li>
</ul>
</li>
<li><strong>controller-to-switch message</strong>(flow table 세팅을 위한 메세지)<ul>
<li>features: controller가 질문하고 switch가 응답함</li>
<li>configure</li>
<li>modify state: openflow table 수정</li>
<li>packet-out: controller가 제어하는 스위치의 지정된 포트에서 특정 패킷을 내보낸다.</li>
</ul>
</li>
<li><strong>switch-to-controller message</strong><ul>
<li>packet in: packet을 controller에게 전달</li>
<li>flow-removed: flow table entry를 삭제한다.(시간 만료나 modify state 메세지 수신한 경우)</li>
<li>port status: 스위치가 port의 상태를 controller에게 알리기</li>
</ul>
</li>
</ul>
</li>
<li><strong>다익스트라 LS가 SDN으로 동작하는 예시</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/e24ff831-dae7-4c3f-8c6e-bf197d54b44d/image.PNG" alt="">
<img src="https://velog.velcdn.com/images/gb_leem/post/29cf5daf-5356-4510-a052-a26b16476fea/image.PNG" alt=""></li>
<li>SDN의 문제점<ul>
<li>중앙집중형이므로.. 한번에 고장남<h2 id="6-internet-control-message-protocol">6. Internet Control Message Protocol</h2>
</li>
</ul>
</li>
<li>ICMP<ul>
<li>host와 라우터의 통신할때 사용 (3계층에서-network layer)</li>
<li><strong>error reporting 할때 많이 사용한다.</strong></li>
</ul>
</li>
<li>Traceroute and ICMP<ul>
<li>출발지에서 도착지까지의 경로 구하기(출발지와 목적지 사이의 라우터 이름과 주소를 알아내기)</li>
<li>도착지에 도달하면 &quot;port unreachable&quot; 메세지를 통해 도착지에 도달한 것을 알 수 있다.<h2 id="7-network-management-configuration">7. Network Management, configuration</h2>
</li>
</ul>
</li>
<li>skip*</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[컴퓨터 네트워크 4 : Network Layer]]></title>
            <link>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-4-Network-Layer</link>
            <guid>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-4-Network-Layer</guid>
            <pubDate>Fri, 08 Dec 2023 18:22:05 GMT</pubDate>
            <description><![CDATA[<h2 id="1-network-layer-overview">1. Network Layer: overview</h2>
<ul>
<li>network layer의 sevice 와 protocols<ul>
<li>sender는 <strong>segments</strong>(transport layer의 packet)를 encapsulate 하여 <strong>datagram</strong>(network layer의 packet)으로 만들어서 보내기</li>
<li>receiver는 segment 를 추출해서 transport layer로 보내기</li>
</ul>
</li>
<li>network-layer functions<ul>
<li><strong>forwarding</strong> <ul>
<li>라우터 안에서 패킷을 적절한 output 링크로 보내주기</li>
<li>data plane과 관련!</li>
</ul>
</li>
<li><strong>routing</strong> <ul>
<li>패킷 경로를 설정하기</li>
<li>control plane과 관련!<h3 id="1-1-data-plane">1-1. data plane</h3>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>local</strong>, per-router function</li>
<li>forwarding table을 통해 router의 input port로 들어온 datagram이 적합한 output port로 나가도록 하는 것<h3 id="1-2-control-plane">1-2. control plane</h3>
</li>
<li><strong>network-wide</strong></li>
<li>전체 packet 전송 과정에서 source에서 destination으로 갈 때 어떤 경로를 통해 갈 것인지 설정</li>
<li><strong>two control-plane approaches</strong><ul>
<li>전통적인 방식 : 라우터에 구현하기
<img src="https://velog.velcdn.com/images/gb_leem/post/35944767-93c1-45d9-925e-5b3ae1283121/image.PNG" alt=""></li>
<li><strong>SDN (software-defined networking)</strong> : routing 기능을 별도의 서버에 구현하기
<img src="https://velog.velcdn.com/images/gb_leem/post/90db82f9-f339-40ce-9df4-a5e445213e9d/image.PNG" alt=""></li>
</ul>
</li>
</ul>
<h3 id="1-3-network-service-model">1-3. network service model</h3>
<ul>
<li>정의 : <strong>송수신 호스트 간 패킷 전송 특성</strong></li>
<li>서비스의 예시..<ul>
<li>보장된 전달</li>
<li>지연 제한 이내의 보장된 전달</li>
<li>순서화 패킷 전달</li>
<li>최소 대역폭 보장</li>
<li>보안 서비스</li>
</ul>
</li>
<li><strong>best effort service</strong><ul>
<li>보장된 것이 없는 서비스<ul>
<li>순서 보장 x</li>
<li>전송 자체 보장 x</li>
<li>지연, 최소 대역폭 보장 x</li>
</ul>
</li>
</ul>
</li>
<li>cf) QoS (Quality of Service)<h2 id="2-whats-inside-a-router">2. What&#39;s inside a router</h2>
<h3 id="2-1-input-ports-switching-output-ports">2-1. input ports, switching, output ports</h3>
전체적인 모습
<img src="https://velog.velcdn.com/images/gb_leem/post/0355e4cb-dbb2-488c-a02b-7973b31624bc/image.PNG" alt=""></li>
<li><strong>Input Ports</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/ced0dce0-afa6-48a6-965c-ad7f0493922e/image.PNG" alt=""><ul>
<li>line termination : physical layer의 값 처리 (bit level)</li>
<li>link layer protocol</li>
<li>look up, forwarding queueing (decentralized switching)<ul>
<li>검색기능 (header를 통해 output찾기)    </li>
<li><strong>destination-based forwarding</strong><ul>
<li>목적지 주소를 보고 forwarding 하기</li>
<li>주소값의 범위를 가지고 앞에서부터 비교해서 어느 지점까지 확인해서 output 링크를 정하는 방식</li>
<li><strong>Longest prefix matching</strong><ul>
<li>비교한 것이 같을 때 처리하는 방식</li>
<li>가장 길게 matching 되는 것 선택하기</li>
<li>TCAMs 라는 메모리 사용함 (빠르다)</li>
</ul>
</li>
</ul>
</li>
<li><strong>generalized forwarding</strong> <ul>
<li>다른 정보를 추가로 활용한 forwarding</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>Switching</strong><ul>
<li>정의 : input 링크로 들어온 packet을 올바른 output 링크로 연결하는 것</li>
<li>switching rate </li>
<li>많이 사용하는 방식 세가지<ul>
<li><strong>memory</strong><ul>
<li>입력포트와 출력포트를 연결하는 system bus에 있어서 메모리라는 중간 매개체를 이용</li>
<li>packet이 system memory로 복사된 후 보내진다.</li>
<li>복사를 해야하기 때문에 속도가 느리다.</li>
</ul>
</li>
<li><strong>bus</strong><ul>
<li>공유하는 하나의 bus를 사용</li>
<li>동시전송이 안되고, 하나의 input을 처리할때 bus를 독점해야 한다.</li>
</ul>
</li>
<li><strong>interconnection network</strong><ul>
<li>동시에 통신을 가능하게 하는 방법</li>
<li>multistage switch<ul>
<li>nxn switch 사용</li>
</ul>
</li>
<li>exploiting parallelism         </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>Output Ports</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/97490219-bb7d-4862-9caa-27e9ad96598e/image.PNG" alt=""><ul>
<li>cf) Input Port queuing<ul>
<li>입력 대비 switch가 느리게 동작하는 것을 방지하기 위해 존재</li>
<li>Head-of-the-Line blocking</li>
<li>가끔 발생할 수 있는 일을 방지하기 위해 존재함</li>
</ul>
</li>
<li><strong>Output Port Queuing</strong><ul>
<li>buffering : 꽉 찼을때 버리기</li>
<li>scheduling discipline : 우선순위를 통해 큐에서 보낼 것 정하기<h3 id="2-2-buffer-management-scheduling">2-2. buffer management, scheduling</h3>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>Buffer Management</strong><ul>
<li>drop : packet을 버리는 방식<ul>
<li><strong>tail drop</strong>: 맨 뒤에(꼬리)에 있는것 버리기</li>
<li><strong>priority</strong>: 우선순위 정해서 버리기</li>
</ul>
</li>
<li>marking : 마킹해두기<ul>
<li>ECN, RED</li>
</ul>
</li>
</ul>
</li>
<li><strong>Scheduling</strong><ul>
<li><strong>FCFS</strong> : first come first served (먼저 온 것 먼저 보내기)</li>
<li><strong>Priority</strong> : 헤더를 통해 우선순위 구별하기<ul>
<li>low pri와 high pri가 존재해서 low 의 경우 high가 모두 보내진 다음 보내게 되어있다. 
<img src="https://velog.velcdn.com/images/gb_leem/post/5c77c1b9-1a50-4742-8039-0ac88f168615/image.PNG" alt=""></li>
</ul>
</li>
<li><strong>Round Robin</strong><ul>
<li>큐의 우선순위에 따라 돌아가면서 쓰는 방식</li>
<li>각 큐는 같은 가중치를 가진다.</li>
</ul>
</li>
<li><strong>Weighted fair queueing</strong><ul>
<li>RR의 진화된 방식 -&gt; <strong>많이 사용되는 큐의 가중치를 더 많이 주어서 더 많이 반복되게 한다!</strong></li>
<li>최소 bandwidth가 보장된다.</li>
<li>QoS를 지킨다.<h2 id="3-ip-the-internet-protocol">3. IP: the Internet Protocol</h2>
</li>
</ul>
</li>
</ul>
</li>
<li>Network Layer: Internet
<img src="https://velog.velcdn.com/images/gb_leem/post/31f047c6-7237-4881-8e05-e17eff67df33/image.PNG" alt=""><h3 id="3-1-datagram-format">3-1. datagram format</h3>
<img src="https://velog.velcdn.com/images/gb_leem/post/a39c04c6-527e-4daf-9bcc-c1240bc6f96f/image.jpg" alt=""><h3 id="3-2-addressing">3-2. addressing</h3>
</li>
<li>Intro<ul>
<li>IP address: 라우터나 호스트를 구별하기 위한 식별자</li>
<li>Interface : 호스트와 물리적 링크 사이의 경계</li>
</ul>
</li>
<li><strong>Subnets</strong><ul>
<li><strong>라우터 없이</strong> 물리적으로 서로에게 도달할 수 있는 장치 인터페이스</li>
<li>subnet 주소 예시
<img src="https://velog.velcdn.com/images/gb_leem/post/c322e722-98f7-4373-899d-5a4fc51a9c6b/image.PNG" alt="">
<img src="https://velog.velcdn.com/images/gb_leem/post/099e96e7-141a-488c-82c8-82a1f6785abe/image.PNG" alt=""></li>
</ul>
</li>
<li><strong>CIDR(Classless InterDomain Routing)</strong><ul>
<li>subnet 주소체계 표기를 일반화 하기</li>
<li>a.b.c.d/x의 형식<ul>
<li>x는 subnet 주소의 길이를 알려줌</li>
</ul>
</li>
</ul>
</li>
<li><strong>DHCP(Dynamic Host Configuration Protocol)</strong><ul>
<li>서버로부터 동적으로 IP 할당받기</li>
<li>동작 과정
<img src="https://velog.velcdn.com/images/gb_leem/post/21a1e6ea-5850-4857-93b8-adb9fde5850e/image.jpg" alt=""><ul>
<li><strong>DHCP discover</strong>를 통해 DHCP 서버 존재여부 확인</li>
<li><strong>DHCP offer</strong>를 통해 사용할 수 있는 IP 주소 알려줌</li>
<li><strong>DHCP request</strong>를 통해 사용하겠다고 알려줌</li>
<li><strong>DHCP ACK</strong>을 통해 IP 주소 사용 확인</li>
</ul>
</li>
<li>IP 주소뿐만 아니라 첫번째 홉 라우터의 주소나, DNS서버의 정보 network mask등의 정보도 DHCP가 준다.</li>
</ul>
</li>
<li>how to get IP address?<ul>
<li>IP 주소의 subnet part의 경우는 주소를 바꾸지 못한다.</li>
<li>그 뒤에 수정 가능한 부분을 수정하기</li>
</ul>
</li>
<li><strong>Hierarchical addressing</strong><ul>
<li>route aggregation</li>
<li>IP 주소가 ~ 로 시작하는 것끼리 묶어두어 더 효율적으로 addressing 할 수 있다.</li>
<li>여기서도 long dest prefix에 따라 동작하므로, 만일 1번 ISP의 Organization이 2번으로 간 경우라도 제대로 동작한다.<h3 id="3-3-natnetwork-address-translation">3-3. NAT(Network Address Translation)</h3>
<img src="https://velog.velcdn.com/images/gb_leem/post/ec1bad42-1f05-4622-b109-6666bdeaf572/image.PNG" alt=""></li>
</ul>
</li>
<li>정의 : 바깥세상(rest of Internet)으로 나갈 때 사설IP를 진짜 IP로 변환해주는 것</li>
<li>port# 를 통해 사설 IP를 구별한다.</li>
<li>cf) NAT는 network 계층인데,  port#(transport layer)를 건드리는것은 원칙은 아니지만, 동작하는데 문제없어서 그냥 쓰고 있다.<h3 id="3-4-ipv6">3-4. IPv6</h3>
</li>
<li>IPv6가 나오게 된 동기<ul>
<li>IP 주소의 고갈 (IPv6 -&gt; 128bit)</li>
<li>speed processing (빠른 처리와 forwarding, IP packet 단순화) -&gt; <strong>간소화된 header</strong></li>
<li>서로 다른 flow에서 서로다른 network 처리 (QoS)</li>
</ul>
</li>
<li><strong>datagram format 특이점 (IPv4와 차이점)</strong><ul>
<li>no checksum, fragmentation, options</li>
</ul>
</li>
<li><strong>tunneling</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/ea9cf42c-58f7-430c-951d-d607287d9362/image.PNG" alt=""><ul>
<li>IPv4를 IPv6로 전환하는 과정!</li>
<li>IPv6를 IPv4처럼 캡슐화 해서 진행<ul>
<li>예를들어 A-&gt;F 경로 중 C,D가 IPv4 터널일때 B-&gt;E까지의 경로로 캡슐화해서 진행<h2 id="4-generalized-forwarding-sdn">4. Generalized Forwarding, SDN</h2>
<h3 id="4-1-matchaction">4-1. Match+Action</h3>
</li>
</ul>
</li>
</ul>
</li>
<li>정의<ul>
<li><strong>Match</strong> : 목적지의 IP 주소를 찾기</li>
<li><strong>Action</strong> : 패킷을 지정된 출력 포트로 전송</li>
</ul>
</li>
<li><strong>Generalized forwarding vs. Destination based forwarding</strong><ul>
<li>destination based forwarding은 오직 도착지 주소만 가지고 수행하지만, generalized 는 다양한 헤더들을 통해 action을 수행한다.  </li>
</ul>
</li>
<li><strong>Flow table(forwarding table)</strong><ul>
<li><strong>flow</strong> : 헤더값에 정의되어 있다.</li>
<li><strong>generalized forwarding</strong> <ul>
<li>match </li>
<li>action : drop, forward, modify 등등</li>
<li>priority : 중복 제거?</li>
<li>counters : 얼마나 사용했는지<h3 id="4-2-openflow-matchaction-in-action">4-2. OpenFlow: match+action in action</h3>
</li>
</ul>
</li>
</ul>
</li>
<li>간단한 forwarding 예시
<img src="https://velog.velcdn.com/images/gb_leem/post/9a6ac8b5-a8a1-4d75-9889-0284a2d4cd08/image.PNG" alt=""></li>
<li>load balancing
<img src="https://velog.velcdn.com/images/gb_leem/post/5dcaeb19-2d0f-4bb0-adf3-53258d9f3e0b/image.jpg" alt=""></li>
<li>firewall
<img src="https://velog.velcdn.com/images/gb_leem/post/a9b27c45-9bde-40c5-a2a3-2a5cb6b23b6d/image.jpg" alt=""></li>
<li>요약<ul>
<li>router<ul>
<li>match: 가장 긴 도착지 IP prefix</li>
<li>action: forward out a link</li>
</ul>
</li>
<li>switch<ul>
<li>match: 도착지 MAC 주소</li>
<li>action: forward or flood</li>
</ul>
</li>
<li>firewall<ul>
<li>match: IP 주소, TCP/UDP 포트#</li>
<li>action: permit or deny</li>
</ul>
</li>
<li>NAT<ul>
<li>match: IP 주소, port#</li>
<li>action: 주소와 port 다시 쓰기<h2 id="5-middleboxes">5. Middleboxes</h2>
</li>
</ul>
</li>
</ul>
</li>
<li>RFC 3234: &quot;출발지 호스트와 목적지 호스트 사이의 데이터 경로에서 IP 라우터의 정상적이고 표준적인 기능과는 별도로 기능을 수행하는 모든 미들박스&quot;</li>
<li><strong>Middlebox의 역할</strong><ul>
<li>NAT</li>
<li>보안 (Firewall, IDS)</li>
<li>성능 향상 (Load balancer, Cache)</li>
</ul>
</li>
<li><strong>&quot;whitebox&quot; hardware</strong><ul>
<li><strong>network를 sw화 해서 범용으로 쓸 수 있게 만들었다.</strong></li>
<li>SDN</li>
<li>NFV(Network Functions Virtualization)<ul>
<li>whitebox위에 어떤 sw를 설치하는가에 따라 다른 역할을 할 수 있도록 만들기</li>
</ul>
</li>
<li>IP hourglass<ul>
<li>초기 : IP 가 유일한 network layer protocol</li>
<li><strong>중기 : IP, NAT, caching, NFV, Firewall (middle box 들)</strong></li>
</ul>
</li>
</ul>
</li>
<li><strong>결론은 Internet의 core를 simple하게 만들고, 복잡한 것들은 Internet edge에 배치하기</strong></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[컴퓨터 네트워크 3 : Transport Layer 2]]></title>
            <link>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-3-Transport-Layer-2</link>
            <guid>https://velog.io/@gb_leem/%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-3-Transport-Layer-2</guid>
            <pubDate>Tue, 31 Oct 2023 17:54:03 GMT</pubDate>
            <description><![CDATA[<h2 id="5-connection-oriented-transport-tcp">5. Connection-oriented transport: TCP</h2>
<h3 id="segment-structure--reliable-data-transfer">&lt;segment structure &amp; reliable data transfer&gt;</h3>
<h3 id="1-tcp-overview">1. TCP overview</h3>
<ul>
<li>point to point (1:1 통신) <ul>
<li>cf1) 1 : 모두 -&gt; broadcast</li>
<li>cf2) 1 : 다수 -&gt; multicast</li>
</ul>
</li>
<li>reliable, in-order byte stream</li>
<li>full duplex data<ul>
<li>하나의 링크를 통해 데이터 보내고 받기 수행</li>
</ul>
</li>
<li>cumulative ACKs</li>
<li>pipelining<ul>
<li>congestion and flow control </li>
</ul>
</li>
<li>connection-oriented</li>
<li>flow controlled</li>
</ul>
<h3 id="2-tcp-segment-structure">2. TCP segment structure</h3>
<ul>
<li>source port, dest port</li>
<li>seq #</li>
<li>ack #</li>
<li>checksum</li>
<li>receive window : for flow control</li>
<li>C,E : congestion 알려주는 것</li>
<li>data<h3 id="3-tcp-sequence-numbers-acks">3. TCP sequence numbers, ACKs</h3>
</li>
<li>telnet?<h3 id="4-tcp-round-trip-time-timeout">4. TCP round trip time, timeout</h3>
</li>
<li>timeout값을 정하는 기준<ul>
<li>RTT의 평균보다는 큰 값</li>
<li>너무 작으면 성급한 timeout 발생</li>
<li>너무 크면 반응이 느려짐</li>
</ul>
</li>
<li>RTT 측정<ul>
<li>sampleRTT : segment를 받은 시간부터 해당 segment에 대한 ACK이 오기 전까지 시간</li>
<li>sampleRTT는 불규칙하다!</li>
<li>해결 : sampleRTT의 평균치 구하기 -&gt; <strong>EstimatedRTT</strong></li>
</ul>
</li>
<li>EstimatedRTT<ul>
<li>$EstimatedRTT=(1-\alpha)<em>EstimatedRTT + \alpha</em>SampleRTT$</li>
</ul>
</li>
<li><strong>exponential weighted moving average (EWMA)</strong><ul>
<li>최근 sample에 대한 값의 우선순위 주기!</li>
<li>더 smooth 한 결과를 얻을 수 있다.</li>
</ul>
</li>
<li><strong>timeoutInterval</strong><ul>
<li>$TimeoutInterval = EstimatedRTT+4*DevRTT$</li>
<li>4*DevRTT는 safety margin (여윳값)</li>
</ul>
</li>
<li><strong>DevRTT</strong>(RTT변화율, 표준편차)<ul>
<li>$DevRTT = (1-\beta)<em>DevRTT+\beta</em>|SampleRTT-EstimatedRTT|$</li>
<li>sample이 평균으로부터 얼마나 떨어져있는가..<h3 id="5-tcp-sender">5. TCP sender</h3>
</li>
</ul>
</li>
<li>application으로 부터 data받기</li>
<li>timeout</li>
<li>ACK received<h3 id="6-tcp-receiver">6. TCP receiver</h3>
</li>
<li>arrival in-order</li>
<li>out of order<h3 id="7-tcp-retransmission-scenarios">7. TCP: retransmission scenarios</h3>
</li>
<li>lost ACK</li>
<li>premature timeout</li>
<li>cumulative ACK covers for earlier lost ACK</li>
</ul>
<h3 id="flow-control--connection-management">&lt;flow control &amp; connection management&gt;</h3>
<h3 id="8-tcp-flow-control">8. TCP flow control</h3>
<ul>
<li><strong>Congestion control</strong> 이랑 다른것</li>
<li>수신하는 application의 읽는 속도와 송신자가 전송하는 속도를 같게 하는 것</li>
<li>TCP segment structure에 존재하는 receive window 사용</li>
<li>과정 <ul>
<li>receive window는 수신측에서 가용한 버퍼 공간이 얼마인지 송신자에게 알려준다.</li>
<li>수신자는 수신 받을 것이 생기면 수신 버퍼(RcvBuffer)를 할당한다.</li>
<li>수신버퍼에 저장된 번호 - 버퍼로부터 읽은 번호 &lt;= RcvBuffer 인 경우를 유지해서 넘치지 않게 한다.</li>
<li>rwnd = RcvBuffer-(수신버퍼 저장된 번호 - 버퍼로부터 읽은 번호) 수식을 만족하는 동적인 공간이 존재한다.<h3 id="9-tcp-connection-management">9. TCP connection management</h3>
</li>
</ul>
</li>
<li>데이터를 교환하기 전에 sender와 receiver가 <strong>handshake</strong> 하기</li>
<li><strong>2-way handshake 쓰면 안되는 이유</strong><ul>
<li>variable delay<ul>
<li>client는 timeout 발생했지만, server는 응답을 보낸경우 -&gt; half open 상태</li>
</ul>
</li>
<li>message loss &amp; reordering</li>
<li>client와 server는 각자 다른 쪽의 상태를 모른다.</li>
</ul>
</li>
<li>3-way handshake과정<ul>
<li>SYN이라는 1비트 보내기(sent 상태), client_isn 선택하여 seq #에 넣기</li>
<li>server host는 TCP SYN 추출 / 다시 응답을 보낼때 SYN은 1로(receive상태) seq#는 server_isn으로 ACK#을 client_isn+1로 설정해서 보낸다.</li>
<li>다시 client가 응답을 받으면 SYN은 0으로 seq#는 client_isn+1로 ACk#은 server_isn+1로 설정한다.<h2 id="6-principles-of-congestion-control">6. Principles of congestion control</h2>
<h3 id="1-introduction">1. introduction</h3>
</li>
</ul>
</li>
<li><strong>congestion : network가 처리하기에 너무 많은 양의 data가 들어옴</strong></li>
<li><strong>long delay</strong></li>
<li><strong>packet loss</strong><h3 id="2-causescost-of-congestion">2. Causes/cost of congestion</h3>
<h4 id="1-scenario-1-2개의-송신자와-무한-버퍼-라우터-하나">1. scenario 1: 2개의 송신자와 무한 버퍼 라우터 하나</h4>
</li>
<li>packet 손실 x, 라우터의 용량 R, throughput R/2</li>
<li>링크를 둘이서 공유해야 하므로 R/2가 최대 값</li>
<li>packet이 불규칙적으로 들어오는 경우 R/2 부근에서 지연이 무한대가 된다.
<img src="https://velog.velcdn.com/images/gb_leem/post/1742aeaf-1e75-42e6-8f55-298bc2f1b2b9/image.PNG" alt=""><h4 id="2-scenario-2-2개의-송신자-유한-버퍼-라우터">2. scenario 2: 2개의 송신자, 유한 버퍼 라우터</h4>
</li>
<li>retransmit lost, time-out packet</li>
<li>버퍼가 가득찬 상황에서 도착한 패킷은 버려짐 -&gt; 재전송 필요</li>
<li>재전송을 하게되면 보내야 하는 양이 늘어남 </li>
<li>종류<ul>
<li>perfect knowledge
<img src="https://velog.velcdn.com/images/gb_leem/post/0ef22076-ac2f-4b15-9cda-b86197f9f1e1/image.PNG" alt=""></li>
<li>some perfect knowledge<ul>
<li>retransmissions 때문에 끝에서 꺾인다.
<img src="https://velog.velcdn.com/images/gb_leem/post/e2e817a1-a8f1-41fe-98ae-d4a6d1e275a3/image.PNG" alt=""></li>
</ul>
</li>
<li>un-needed duplicates
<img src="https://velog.velcdn.com/images/gb_leem/post/61414551-64d2-4915-a8aa-e0d51fcc538f/image.PNG" alt=""></li>
</ul>
</li>
</ul>
<h4 id="3-scenario-3-4개의-송신자-유한-버퍼-라우터-멀티홉">3. scenario 3: 4개의 송신자, 유한 버퍼 라우터, 멀티홉</h4>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/c2d9b3e0-1723-40fc-b8b7-08c2b72f2073/image.PNG" alt=""></p>
<h3 id="3-approaches-towards-congestion-control">3. Approaches towards congestion control</h3>
<ul>
<li>congestion에 대한 정보는 network 계층이 가장 잘 안다. 그러나 network 계층은 혼잡 처리에 대해 아무일도 하지 않는다. -&gt; host가 혼잡제어 하기</li>
<li><strong>End-End congestion control</strong> <ul>
<li>network 계층의 피드백 없는 경우</li>
<li>RTT나 timeout을 통해 추론하기</li>
</ul>
</li>
<li><strong>Network-assisted congestion control</strong><ul>
<li>router가 최소한의 피드백을 전해준다.</li>
<li>ex) TCP ECN<h2 id="7-tcp-congestion-control">7. TCP congestion control</h2>
<h3 id="1-tcp-congestion-control-aimd">1. TCP congestion control: AIMD</h3>
</li>
</ul>
</li>
<li><strong>Additive Increase Multiplicative Decrease</strong>
<img src="https://velog.velcdn.com/images/gb_leem/post/986478b2-e10f-4f12-ad20-f307af29b6dc/image.PNG" alt=""></li>
<li>Additive Increase<ul>
<li>시간에 따라 선형적으로 네트워크에 주입되는 data양을 늘리기</li>
<li>AI 수행 후 MD 수행</li>
</ul>
</li>
<li>Multiplicative Decrease<ul>
<li>혼잡이 생긴 부분에서 data양을 확 줄이기</li>
<li>MD 수행 후 다시 AI 수행<h3 id="2-tcp-overview">2. TCP overview</h3>
</li>
</ul>
</li>
<li>TCP 혼잡의 증상
1) timeout (2번보다 심각한 문제)
2) 3 duplicate ACKs</li>
<li>TCP Tahoe <ul>
<li>가장 초기의 TCP</li>
<li>TCP혼잡 증상인 1,2에 대해 모두 동일하게 처리 </li>
<li>sending rate를 1로 돌아가서 다시 올라오기</li>
</ul>
</li>
<li>TCP Reno<ul>
<li>1의 경우는 Tahoe처럼 처리</li>
<li>2의 경우는 congestion 값 * 0.5에서 다시 시작하기<h3 id="3-tcp-congestion-control-details">3. TCP congestion control: details</h3>
</li>
</ul>
</li>
<li>CWND : receiver에 상관없이 sender가 보낼 수 있는 최대 값</li>
<li>TCP rate (throughput) = $\frac{CWND}{RTT}bytes/sec$</li>
<li>(LastByteSent - LastByteACKed) &lt;=CWND</li>
</ul>
<h3 id="4-tcp-slow-start">4. TCP slow start</h3>
<ul>
<li>TCP rate를 1-&gt;2-&gt;3-&gt;4-&gt; ... 올리면 너무 오래걸리기때문에 지수 형태로 1-&gt;2-&gt;4-&gt;8-&gt;... 로 올리기</li>
<li>slow start의 threshold (SST)는 지수형태로 올라가다가 AIMD로 바뀌는 지점이다. <h3 id="5-tcp-from-slow-start-to-congestion-avoidance">5. TCP: from slow start to congestion avoidance</h3>
<img src="https://velog.velcdn.com/images/gb_leem/post/00afc957-3a1d-4c7c-b3dd-a72056f65ed7/image.PNG" alt=""></li>
<li><strong>위 그림에서 Reno는 round 9 에서 cwnd 9에서 부터 시작해야함!! - 그림 틀렸음</strong></li>
<li>if) duplicate ACK 상황에 12에서 congestion 발생<ul>
<li>위의 그래프에서 Tahoe인 경우 1로 내려가서 slow start로 다시 시작후 SST가 6이므로 이때부터 AIMD 수행</li>
<li>Reno인 경우 6에서 다시 시작 SST가 6이므로 바로 AIMD 수행</li>
</ul>
</li>
</ul>
<h3 id="6-summary-tcp-congestion-control">6. summary: TCP congestion control</h3>
<p><img src="https://velog.velcdn.com/images/gb_leem/post/fe32dfb0-fe18-4f43-a355-9600488ce951/image.PNG" alt=""></p>
<h3 id="7-tcp-cubic">7. TCP CUBIC</h3>
<ul>
<li>TCP Reno의 다음 버전 (Linux의 default)</li>
<li>한번 혼잡이 발생한 이후 가까운 다음 시점에도 혼잡 발생한 시점이 비슷할것이기 때문에 최대 window size(W_max) 까지는 급격하게 올리고 근처에서 천천히 올리기
<img src="https://velog.velcdn.com/images/gb_leem/post/0c8eb896-091f-46e7-89e3-5d5e7b15e397/image.PNG" alt=""></li>
</ul>
<h3 id="8-tcp-and-the-congested-bottleneck-link">8. TCP and the congested &quot;bottleneck link&quot;</h3>
<ul>
<li>bottleneck link : data가 전송이되는 링크는 항상 혼잡하지 않아야 한다</li>
</ul>
<h3 id="9-delay-based-tcp-tcp-vegas">9. Delay-based TCP (TCP Vegas)</h3>
<ul>
<li>just full enough, but no fuller!</li>
<li>bottleneck link가 넘치치 않을 정도로 바쁘게 하기</li>
<li>Throughput = $\frac{CWND}{RTTmin}$ : 혼잡하지 않을때 처리율</li>
<li>ex) BBR<h3 id="10-explicit-congestion-notification-ecn">10. Explicit congestion notification (ECN)</h3>
</li>
<li><strong>network로 부터 congestion에 대한 정보 받아오는 방식</strong></li>
<li>TCP segment에 존재하는 C,E field 이용</li>
<li>여기서 congestion 하다는 정보는 주지만, 이에 대한 처리는 각자 다른 방식으로 하는것</li>
</ul>
<h3 id="11-tcp-fairness">11. TCP fairness</h3>
<ul>
<li>bottleneck router capacity이 R이고 TCP session이 K개 있다면 하나당 R/K의 속도 가진다.</li>
<li>TCP는 fair 하다! -&gt; 아래의 그림으로 증명
<img src="https://velog.velcdn.com/images/gb_leem/post/439a0de0-d9e1-475a-b5b2-c6b31ec6ec85/image.PNG" alt=""></li>
<li>위의 그림을 통해 어떠한 곳에서 시작해도 결국 bandwidth 가 같은 선위로 가게 된다. (AIMD로 동작하는 것)</li>
</ul>
<h3 id="12-must-all-network-apps-be-fair">12. must all network apps be fair?</h3>
<ul>
<li>UDP는 fair 하지 않음</li>
<li>TCP가 fair 하다는 것은 host 기반으로 봤을땐 fair하지 않음</li>
</ul>
<h2 id="8-evolution-of-transport-layer-functionality">8. Evolution of transport-layer functionality</h2>
<h3 id="1-quic-quick-udp-internet-connections">1. QUIC: Quick UDP Internet Connections</h3>
<ul>
<li>TCP와 UDP의 중간 지점</li>
<li>application layer에 QUIC라는 protocol을 올림 (아래 오른쪽 그림)
<img src="https://velog.velcdn.com/images/gb_leem/post/ba1e02da-2398-41b3-a9a3-1ac6b91ae0b5/image.PNG" alt=""></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>