<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>eeminsu's Devlog</title>
    <link>https://immigrationssu.tistory.com/</link>
    <description>개발일지</description>
    <language>ko</language>
    <pubDate>Wed, 27 May 2026 16:18:44 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>eeminsu</managingEditor>
    <item>
      <title>[F-Lab] Java 백엔드 코스 3개월 솔직후기</title>
      <link>https://immigrationssu.tistory.com/entry/F-Lab-Java-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%BD%94%EC%8A%A4-3%EA%B0%9C%EC%9B%94-%EC%86%94%EC%A7%81%ED%9B%84%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;현재까지 진행한 내용&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링도 어느새 13주차까지 진행하였다. 멘토링을 시작한게 엊그제 같은데 벌써 한달여밖에 남지 않았다.. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1개월차에는 자바에 대한 이론 공부를 깊게한 이후 2개월차부터 스프링에 대한 학습과 프로젝트 기획을 병행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래라면 지금은 프로젝트의 기능을 대부분 구현하고 리팩토링을 하면서 멘토님의 코드리뷰를 받아야하는 단계이지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난달 초에 지원했던 회사들이 운좋게 모두 서류합격이 되면서 면접준비와 프로젝트를 병행하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 병행이라기보다 면접 준비에 더 집중하게 되었는데, 이 부분은 멘토님께서 먼저 프로젝트보다 면접 준비에 무게를 두자고 하셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 멘토님께서 이력서와 경력기술서를 토대로 예상 면접 질문을 뽑아주셨고 모의 면접식으로 멘토링을 진행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이전에도 멘토링 자체가 본인이 학습한 내용에 대해서 질문과 답변을 이어가는 방식이어서 어느 정도 기술 면접에 대비를 할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 한 기업의 기술면접에서 자바에 관해 꼬리질문을 이어가며 깊게 물어보았는데 멘토링때 학습한게 매우 도움이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 기술면접에서 합격을 하게되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컬쳐핏 면접에 대해서도 멘토님께서 본인의 경험을 바탕으로 예상 질문들을 말씀해주시면서 모의 면접을 해주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;덕분에 모든 채용과정을 마치고 최종합격을 하게되었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;340&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvHIMs/btsORXT5YWQ/DgkshXIWukjz7okKO1o5Ok/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvHIMs/btsORXT5YWQ/DgkshXIWukjz7okKO1o5Ok/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvHIMs/btsORXT5YWQ/DgkshXIWukjz7okKO1o5Ok/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvHIMs%2FbtsORXT5YWQ%2FDgkshXIWukjz7okKO1o5Ok%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;340&quot; height=&quot;302&quot; data-origin-width=&quot;340&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프로젝트를 진행하며&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 진행하면서 얻고자 했던 부분은 코드리뷰 경험과 사용해보지 못한 기술 스택 경험이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토님의 코드리뷰를 받으면서 현재 내 잘못된 코드 스타일을 개선해보고 싶었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용해보지 못한 기술 스택을 적용하면서 왜 이런 기술을 사용하는지에 대해서도 제대로 알고 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 상기의 기술한 바와 같이 취업 활동을 병행하고 운좋게 계속해서 채용과정이 진행되면서 프로젝트를 진행하지 못하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분은 살짝 아쉬웠다... &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC5QK0/btsOQR8qosO/hRlOILlK7d7KR1dXAXRqxK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC5QK0/btsOQR8qosO/hRlOILlK7d7KR1dXAXRqxK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC5QK0/btsOQR8qosO/hRlOILlK7d7KR1dXAXRqxK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC5QK0%2FbtsOQR8qosO%2FhRlOILlK7d7KR1dXAXRqxK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;384&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;멘토링을 진행하며&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링을 통해서 얻을 수 있는 부분은 개인마다 다르고, 여러가지가 있겠지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로는 멘탈적으로 안정감을 찾을 수 있어서 굉장히 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길을 헤매고 있을 때 방향을 알려주고, 쓸데없는 고민과 걱정을 하고 있을 때 해당 부분을 해소해주는 것이 나에게 있어 매우 도움이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 면접 준비를 하면서 정말 걱정도 많고 방황할 때마다 멘토님께 고민을 말씀드리면 현실적인 조언과 응원을 해주셔서 잘 이겨낼 수 있었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 남은 멘토링은 회사를 다니면서 진행을 할 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운좋게도 멘토님과 같은 도메인에 취업을 하게 되서 더 많은 도움을 받을 수 있을 것 같아 기대된다 ㅎㅎ&lt;/p&gt;</description>
      <category>ETC.</category>
      <category>f-lab</category>
      <category>F-Lab 3개월 후기</category>
      <category>java 백엔드</category>
      <category>에프랩</category>
      <category>에프랩 3개월 후기</category>
      <category>후기</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/26</guid>
      <comments>https://immigrationssu.tistory.com/entry/F-Lab-Java-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%BD%94%EC%8A%A4-3%EA%B0%9C%EC%9B%94-%EC%86%94%EC%A7%81%ED%9B%84%EA%B8%B0#entry26comment</comments>
      <pubDate>Wed, 25 Jun 2025 21:48:11 +0900</pubDate>
    </item>
    <item>
      <title>[F-Lab] Java 백엔드 코스 2개월 솔직후기</title>
      <link>https://immigrationssu.tistory.com/entry/F-Lab-Java-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%BD%94%EC%8A%A4-2%EA%B0%9C%EC%9B%94-%EC%86%94%EC%A7%81%ED%9B%84%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;현재까지 진행한 내용&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 8주차까지 멘토링을 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느새 전체 멘토링 기간에 반환점을 돌게 되었다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1개월 간 이론 위주 학습이 끝나고 프로젝트를 진행하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 프로젝트 진행 중에도 이론 학습은 병행해야 한다...ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이론 학습은 Java, Spring까지 진행된 상태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이론 학습은 하면서 느끼지만 끝이 없는 기분...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서류 합격이 2곳이 되어 과제 진행과 면접 준비를 병행하다보니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 진행은 더딘 상황이다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토님께서 과제 코드 리뷰와 면접 준비를 같이 해주셔서 이 부분은 참 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;멘토링을 하면서 깨달은 점&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토님께 채용 과제 코드리뷰를 받으면서 제일 많이 느꼈던 것은 &quot;아 이거 알고있던건데&quot; 였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이력서를 쓸데도 마찬가지였다. 분명 다 알고 있던건데 지켜지지 않은 것들이 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혼자 준비했더라면 발견하지 못했을 거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이력서 또한 여러가지 레퍼런스를 제공해주셔서 많은 도움이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이력서 기반으로 면접 진행시 나올만한 질문들에 대해서 실시간으로 던져주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문을 받으면서 느꼈던 점은 구현 당시에 내가 얼마나 문제 해결에 있어 깊게 생각을 안했는지에 대해 알 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토님께서 이런 부분에 대해서 추가로 발생할 수 있는 문제 상황과 해결법에 대해서 설명해주셔서 학습도 하며 면접 대비를 할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 이럴 때 멘토링이 큰 도움이 된다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;프로젝트를 진행하며&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 시작할 시기에 운이 좋게 두곳에서 서류 합격이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시에 채용 과정을 진행하고 있어서 프로젝트를 제대로 진행하지 못하고 있다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 주제를 선정할 때부터 무엇을 할지 고민이 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 클론코딩처럼 특정 서비스를 만들기엔 시간이 부족하다고 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나는 기존 내 경력에서 부족한 부분이나 써보지 못한 기술 스택을 써보기로 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링을 하면서 제일 기대가 됐던 부분이 멘토님의 코드리뷰였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이론 공부와 다르게 코드의 구조는 정답이 없어 어떤 방향으로 코드를 구현해 나가는 것이 좋은 방향인지 스스로 고민이 많은 상태였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분을 현업 시니어 개발자에게 1:1로 코드 리뷰를 받으면서 배워갈 수 있다는 것이 너무 기대되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 면접 준비 때문에 프로젝트의 뼈대만 구현해서 PR을 올렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;귀신같이 쌓이는 멘토님의 피드백..ㅎㅎ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/otAhA/btsN1gVUQW8/Nr8RhofAvtJqhTtmKXiHk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/otAhA/btsN1gVUQW8/Nr8RhofAvtJqhTtmKXiHk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/otAhA/btsN1gVUQW8/Nr8RhofAvtJqhTtmKXiHk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FotAhA%2FbtsN1gVUQW8%2FNr8RhofAvtJqhTtmKXiHk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;757&quot; height=&quot;214&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 리뷰를 받을 수 있어서 내가 놓쳤거나 몰랐던 부분에 대해서 알아갈 수 있어 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2개월이란 시간이 너무 빨리 지나갔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2개월 사이에 기본기를 단단히 다질 수 있었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 공부, 이력서, 면접 등등 여러가지 궁금한 점에 대해서 멘토님의 피드백을 받을 수 있어서 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 남은 2개월 동안 더 많은 것을 얻어갈 수 있도록 노력해야겠다..ㅎㅎ&lt;/p&gt;</description>
      <category>ETC.</category>
      <category>f-lab</category>
      <category>f-lab 2개월 후기</category>
      <category>java 백엔드</category>
      <category>에프랩</category>
      <category>에프랩 2개월 후기</category>
      <category>후기</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/25</guid>
      <comments>https://immigrationssu.tistory.com/entry/F-Lab-Java-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%BD%94%EC%8A%A4-2%EA%B0%9C%EC%9B%94-%EC%86%94%EC%A7%81%ED%9B%84%EA%B8%B0#entry25comment</comments>
      <pubDate>Mon, 19 May 2025 11:48:01 +0900</pubDate>
    </item>
    <item>
      <title>[F-Lab] Java 백엔드 코스 1개월 솔직후기</title>
      <link>https://immigrationssu.tistory.com/entry/F-Lab-Java-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%BD%94%EC%8A%A4-1%EA%B0%9C%EC%9B%94-%EC%86%94%EC%A7%81%ED%9B%84%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;왜 F-Lab인가&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;내가 잘하는 줄 알았다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;펌웨어 개발자로 커리어를 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;전자과를 졸업한 나는 전공 지식이란건 아무것도 없었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;사수도 없었다. 그저 열심히 하는 것 밖에 몰랐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이런 저런 일도 많았지만 잘한다는 소리를 주변 동료, 상사에게 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그러던 중 직무와 다른 업무들이 쏟아졌고 챗바퀴 같은 업무에 지친 나는 백엔드에 흥미가 생기기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;혼자서 독학을 하면서 업무를 병행했다. 체력적인 한계가 왔다. 업무하는 시간이 아까웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;공부 시간을 확보하기 위해 백엔드 전향을 결심하며 퇴사를 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러던 중 영업팀 차장님을 통해서 협력사에서 제의가 들어왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굳이 공백을 가져가며 공부하지 말고 일을 하면서 배우는게 어떻겠냐는 차장님의 권유였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백엔드 경력이 없는 나를 왜 뽑으려고 할까라는 의심과 함께 폐를 끼칠 것만 같아 거절하였으나 협력사의 삼고초려 끝에 입사를 결심했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입사를 하고도 제법 일을 잘했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1년도 되지 않아 프로젝트의 백엔드 개발을 혼자서 맡으며 성공적으로 마무리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 장애도 발생하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여느 스타트업과 마찬가지로 자금이 넉넉치 않아 자체 서비스 개발보다도 외주 개발을 위주로 흘러갔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서는 빠른 구현을 원했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른건 몰라도 빠르게 구현하는 것은 자신 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 이게 실력인줄 알았다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;겠냐?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxnmw3/btsNo1ryVd0/kiAFXTIk4tNRiwvxyElfHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxnmw3/btsNo1ryVd0/kiAFXTIk4tNRiwvxyElfHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxnmw3/btsNo1ryVd0/kiAFXTIk4tNRiwvxyElfHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbxnmw3%2FbtsNo1ryVd0%2FkiAFXTIk4tNRiwvxyElfHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;285&quot; height=&quot;326&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이직을 고민하던 중 중 퇴사하신 분을 통해 연락이 왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀에서 백엔드 개발자를 충원하려고 하는데 관심이 있냐는 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 면접 제안을 받고 부랴부랴 면접 준비를 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예상 질문들에 대한 답을 준비하고 프로젝트를 진행했던 것들을 복기했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접장에 들어섰다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;객체지향이란 뭘까요?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;JPA에서 N+1 문제가 발생했을 때는 어떻게 해결하죠?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꼬리 질문도 이어지고 모르는 질문도 나왔지만 스스로 면접을 잘봤다고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과가 나오기 전까지 연봉 협상할 생각만 했던거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음날 불합격이라는 연락을 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어..? 왜지..?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그제서야 면접을 복기해봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대답을 잘한줄 알았는데 엉뚱한 얘기를 잘도 떠들어 댄것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무 쪽팔렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 그동안 잘하는 줄만 알았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 실상은 기본기도 없는, 구현만 할 줄 아는 코더에 불과했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본기의 중요성을 깨닫게 되었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그래서 왜 F-Lab?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 사정이 어려워지고 결국 모종의 이유로 퇴사를 하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 회사로 이직을 꿈꾸며 이력서를 넣었지만 모두 서류 탈락을 하게 되었고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마음은 더욱 조급해지며 공부 방향성은 계속해서 흔들렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러던 중 인프런 멘토링을 받게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마음이 편안해지고 도움이 많이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 이런 멘토링을 주기적으로 받으면 좋겠다는 생각이 들었고 F-Lab을 알게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후기도 정말 많이 찾아보고 F-Lab을 진행중인 멘티에게 상담도 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 공통적으로 언급되는 키워드는 기본기, 딥다이브, 개발자 마인드였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나에게 가장 부족한 것들이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 다른 업체들 처럼 1티어 서비스 기업의 입사를 보장해주는 듯한 멘트없이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직하게 언급하는 점이 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 F-Lab 멘토링을 시작하게 되었다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;멘토&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;F-Lab은 &lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;1:1로 멘토링이 진행되는 만큼 어떤 멘토를 만나느냐가 중요했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서도 언급했지만 정말 많은 후기글을 봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블로그글부터 시작해서 디시까지..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토와 성향이 맞지 않아 환불받았다는 글도 많이 보여 제일 걱정된 부분이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 F-Lab은 멘토 변경이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토를 선정하는 과정에서도 멘티의 성향을 제출해서 여러 멘토를 선택할 수 있게 리스트업을 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리스트에서도 선택하고픈 멘토가 없다면 별도로 상담을 통해 멘토를 정할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나 또한 멘토님을 추천받아 선택하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후기글에서 대부분 책, 인강을 구매해서 이론 학습을 진행하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토님을 통해 많은 기술 질문을 받아 멘티의 답변에 대해 피드백을 주는 식으로 진행되는 것을 많이 봐왔는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하겠지만 이 부분은 멘토님별로 진행 방식이 다른 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l5X8f/btsNslbXlwY/aovB5cSy7FYU8Daui9rDDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l5X8f/btsNslbXlwY/aovB5cSy7FYU8Daui9rDDK/img.png&quot; data-alt=&quot;멘토님께 받은 슬랙 메세지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l5X8f/btsNslbXlwY/aovB5cSy7FYU8Daui9rDDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl5X8f%2FbtsNslbXlwY%2FaovB5cSy7FYU8Daui9rDDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;301&quot; height=&quot;68&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;멘토님께 받은 슬랙 메세지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 현재 이론 학습에 대해서는 자유도를 부여받고 기술 질문 또한 페이스에 따라 맞춰주시고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 멘탈적으로도 도움되는 말도 많이 해주신다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 공부 외적으로 이직, 진로, 이력서 첨삭 등등 모든 질문이 가능하고, 멘토님도 정성스럽게 답변해주신다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 커리큘럼대로 과외를 해주는 선생이 아니라 같은 업계에 있는 선배, 말그대로 멘토라는 느낌을 많이 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdGsjU/btsNr9CC1x0/E60ar7k8JBMPF0t7BmkWK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdGsjU/btsNr9CC1x0/E60ar7k8JBMPF0t7BmkWK0/img.png&quot; data-alt=&quot;이런 피드백을 받는 재미도 쏠쏠하다..ㅎㅎ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdGsjU/btsNr9CC1x0/E60ar7k8JBMPF0t7BmkWK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdGsjU%2FbtsNr9CC1x0%2FE60ar7k8JBMPF0t7BmkWK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;526&quot; height=&quot;120&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이런 피드백을 받는 재미도 쏠쏠하다..ㅎㅎ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;1개월 동안 배운 것&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링은 한주동안 이론을 학습하고 해당 내용에 대해서 기술 질문을 받는 형식으로 진행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 1개월은 자바를 학습하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토님이 키워드를 몇가지 던져주시고, 꼭 학습해야할 부분에 대해서 말씀해주시면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 주차에는 말씀주신 내용을 학습하고 그 다음 멘토링에서 기술 질문을 받게된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;답변에 대해 피드백을 해주시고 부족한 부분에 대해서는 설명을 해주신다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM 메모리 구조부터 시작해서 객체지향이란 무엇인지, 인터페이스와 추상클래스의 차이는 무엇인지 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현업에서는 그냥 그런가 보다 하고 지나간 부분에 대해서 깊이 학습할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 서술했듯이 멘토님은 과외선생님이 아니다.(단순 강의를 해주는 사람이 아니라는 것이다.)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내가 한주동안 공부한 부분에 대해서 얼마나 깊이 공부했는지, 옳은 방향으로 공부를 했는지 체크해주신다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 정말 깊이 학습할 수 밖에 없다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;단순히 회사를 다니며 혼자 독학을 했을 때와 비교해서 머릿속에 많이 남게되고 산재된 지식들이 연결되는 느낌이었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;물론 학습 자체는 스스로 하지만 매주 멘토님이 방향을 알려주고 공부한 부분을 체크해주는 것이 많은 도움이 된다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;앞으로의 각오&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 차주부터는 슬슬 프로젝트를 시작하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 시작한다고 해서 이론 학습을 멈추는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스스로 지금까지는 공부 습관을 들이는 단계라고 생각하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 시작하더라도 최소한 지금 공부하는 양과 시간, 깊이 있게 학습하기는 유지하는 게 목표다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩테스트도 최소한 2시간씩 공부시간을 가져가고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분도 계속 유지하는 것이 목표다.&lt;/p&gt;</description>
      <category>ETC.</category>
      <category>f-lab</category>
      <category>f-lab 1개월 후기</category>
      <category>java backend</category>
      <category>java backend 멘토링</category>
      <category>에프랩</category>
      <category>에프랩 1개월 후기</category>
      <category>후기</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/24</guid>
      <comments>https://immigrationssu.tistory.com/entry/F-Lab-Java-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%BD%94%EC%8A%A4-1%EA%B0%9C%EC%9B%94-%EC%86%94%EC%A7%81%ED%9B%84%EA%B8%B0#entry24comment</comments>
      <pubDate>Mon, 21 Apr 2025 10:59:45 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Java에서 Hash를 많이 사용하는 이유</title>
      <link>https://immigrationssu.tistory.com/entry/Java-Java%EC%97%90%EC%84%9C-Hash%EB%A5%BC-%EB%A7%8E%EC%9D%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Hash&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwVpY9/btsNfhzmOXV/dGNcuLky2HBkPyl3Kn5wKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwVpY9/btsNfhzmOXV/dGNcuLky2HBkPyl3Kn5wKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwVpY9/btsNfhzmOXV/dGNcuLky2HBkPyl3Kn5wKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwVpY9%2FbtsNfhzmOXV%2FdGNcuLky2HBkPyl3Kn5wKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1142&quot; height=&quot;395&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임의의 크기를 가지는 데이터(문자, 파일 등)를 &lt;b&gt;해시 함수&lt;/b&gt;에 입력하게 되면 고정된 크기의 데이터를 출력하게 되는데 이를 Hash(또는 해시값, 해시코드)라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 함수는 알고리즘을 이용해서 입력받은 키 값으로 키 값의 크기와 상관없이 해시를 만들어 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 함수는 같은 입력값에 대해서 같은 출력값을 보장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;(입력값에 대한 무결성을 보장한다고 한다.)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 값을 이용해서 키 값을 찾는 것은 불가능하여 일방향성을 갖는다고 얘기한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Hash Table&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/epE9Ht/btsNe7w2ZaH/5KyykrSX1lE31UfGHAo3t1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/epE9Ht/btsNe7w2ZaH/5KyykrSX1lE31UfGHAo3t1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/epE9Ht/btsNe7w2ZaH/5KyykrSX1lE31UfGHAo3t1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FepE9Ht%2FbtsNe7w2ZaH%2F5KyykrSX1lE31UfGHAo3t1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;315&quot; height=&quot;230&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 테이블은 이러한 해시 함수를 이용해 키에 대한 해시 코드를 반환받아 해시 코드를 통해 배열(bucket)의 인덱스로 환산해서 데이터의 접근하는 방식의 자료구조이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;(Java에서는 HashTable, HashMap등을 통해 해당 자료구조를 사용할 수 있다.)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 테이블의 필수 조건은 고정된 크기의 배열을 선언하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 테이블의 크기와 상관없이 키를 통해 상수 시간으로 빠르게 데이터에 접근이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스는 해시 코드와 배열의 크기를 나머지 연산을 하여 환산한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;HashCode % 배열의 크기&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환산한 인덱스를 통해 배열에 데이터를 저장하게 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해시 충돌 (Hash Collision)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지 연산을 통해 인덱스를 환산할 때 서로 다른 키더라도 같은 인덱스를 환산하는 경우가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해시 충돌이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 충돌은 2가지 경우에 해당한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1. 서로 다른 키가 같은 해시 코드를 반환한다.&lt;br /&gt;2. 키와 해시 코드가 서로 다르지만 같은 인덱스를 환산한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같은 해시 충돌에 대한 해결 방법으로는 2가지 방법이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;분리 연결법 (Separate Chaining)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMDuax/btsNdi04FkH/gwzmFtwaYSyT9A4oPrvtLK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMDuax/btsNdi04FkH/gwzmFtwaYSyT9A4oPrvtLK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMDuax/btsNdi04FkH/gwzmFtwaYSyT9A4oPrvtLK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMDuax%2FbtsNdi04FkH%2FgwzmFtwaYSyT9A4oPrvtLK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;724&quot; height=&quot;308&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열에 LinkedList를 사용하여 동일한 인덱스를 반환할 경우 List에 추가하는 방식을 사용하여 해시 충돌을 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 동일한 인덱스에 너무 많은 데이터가 저장된다면 List를 탐색해야 하기 때문에 성능이 저하될 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개방 주소법(Open Addressing)&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;선형 조사법 (Linear Probing)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K2DTI/btsNe3O2uTx/k1q0sMjPVgQtQ2klUJdPdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K2DTI/btsNe3O2uTx/k1q0sMjPVgQtQ2klUJdPdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K2DTI/btsNe3O2uTx/k1q0sMjPVgQtQ2klUJdPdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK2DTI%2FbtsNe3O2uTx%2Fk1q0sMjPVgQtQ2klUJdPdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;367&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 충돌이 발생한 배열 방에 다음 비어있는 배열방으로 데이터를 저장하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 경계를 넘어갈 경우 맨 앞으로 넘어가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 비어있는 배열방이 없는 경우 빈 배열방을 탐색하는 시간이 늘어나게 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이차원 조사법 (Quadratic Probing)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctnHLQ/btsNd7xMCOe/LgNUnIMENuVSqwCld0uAXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctnHLQ/btsNd7xMCOe/LgNUnIMENuVSqwCld0uAXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctnHLQ/btsNd7xMCOe/LgNUnIMENuVSqwCld0uAXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctnHLQ%2FbtsNd7xMCOe%2FLgNUnIMENuVSqwCld0uAXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;194&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선형 조사법의 단점을 보완한 방법이 이차원 조사법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선형 조사법에서는 하나씩 배열방을 탐색했다면 이차원 조사법은 제곱으로 빈 배열방을 탐색한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 영역에 데이터가 몰려도 그 영역을 빠르게 벗어날 수 있는 장점이 있으나 동일한 인덱스를 환산할 경우 탐색해왔던 경로를 그대로 탐색하여 빈 배열방을 찾게 되는 단점이 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;더블 해싱 (Double Hashing)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 개의 해시 함수를 사용하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스를 반환하여 해시 충돌이 발생하면 다른 해시 함수를 통해 이동할 폭을 얻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 함수를 두번 사용하다보니 이동 폭이 같을 확률이 매우 적어 서로 다른 보폭으로 빈 배열 방을 탐색하게 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해시 테이블에서 데이터를 삭제할 때&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 테이블에서 데이터를 삭제할 때 분리 연결법을 사용할 경우 LinkedList에서 포인터 값을 수정하여 데이터를 제거하거나 추가할 수 있다. 그러나 개방 주소법의 경우 해시 충돌이 발생하게 되면 빈 배열방에 데이터를 저장하게 되는데 기존 인덱스에 저장된 데이터가 삭제될 경우 해당 배열방에 더미 데이터를 통해서 데이터가 지워졌다는 내용을 남기거나 빈 배열방에 저장한 데이터를 다시 기존 배열방에 옮겨주어야 하는 작업이 발생하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 데이터 삭제시 분리 연결법이 개방 주소법 보다 성능상 이점을 가지고 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Java에서의 Hash&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서는 HashTable과 HashMap을 통해 해시 테이블 자료구조를 제공하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HashTable은 Java 1.0에서 추가된 자료구조로 동시성을 보장하나 구현의 거의 변화가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 HashMap의 경우에는 지속적으로 개선되고 있으니 되도록 HashMap을 사용하는 것을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;(동시성 문제의 경우 java.util.concurrent 패키지의 라이브러리를 사용하면 된다.)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Java의 해시 충돌 해결 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java는 &lt;b&gt;분리 연결법 (Separate Chaining)&lt;/b&gt;을 사용하여 해시 충돌을 해결하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 LinkedList를 사용하는 것이 아니라 레드-블랙 트리도 혼용된 방식으로 사용하고 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Java 8부터 해당 방식을 사용하게 되었는데 상수 형태로 기준을 정하게 된다.&lt;br /&gt;동일 버킷에 데이터가 8개가 넘게 되면 LinkedList대신 레드-블랙 트리로 자료구조를 변경한다.&lt;br /&gt;그러다 데이터가 6개가 되면 다시 LinkedList로 자료구조를 변경한다.&lt;br /&gt;&lt;br /&gt;2라는 버퍼를 둔 이유는 1개 차이로 데이터의 삽입/삭제가 빈번하게 발생할 경우 불필요한 자료구조 변경으로 인해 성능 저하를 막기 위함이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상기에 기술하였듯이 주소 개방법이 데이터 삭제에 있어서 처리가 효율적이지 않기 때문에 Java에서는 분리 연결법을 채택하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버킷에 저장된 데이터가 일정 개수 이상으로 많아지면 일반적으로 주소 개방법이 분리 연결법보다 느리게 되는데 주소 개방법의 경우 버킷을 채운 밀도가 높아질 수록 Worst Case 발생 빈도가 높아지기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주소 개방법의 경우 보조 해시 함수를 통해서 해시 충돌이 발생하지 않도록 조정한다면 Worst Case가 발생하는 것을 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Hash Table Resizing&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열(버킷)에 데이터가 일정 수준 차이게 되면 크기를 늘려줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서 HashMap의 경우 전체 버킷 크기(capacity)가 75%가 차게 되면 버킷의 크기를 2배 늘려주게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 75%라는 수치를 로드 팩터라고 하는데 HashMap, HashSet등 생성자를 통해 설정해줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 기존 버킷에 저장된 데이터들은 늘어난 버킷 사이즈를 통해 해시 코드와 나머지 연산을 하여 다시 인덱스를 환산해 데이터를 저장하게 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Java에서의 HashMap Resizing&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상기에 기술하였듯이 Java에서는 버킷을 resizing할 때 항상 2배로 늘려주게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이말은 즉, 해시코드와 버킷 갯수를 나머지 연산 할때 해시 코드의 하위 x개의 비트만 사용하게 된다는 말이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;175&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mZXWL/btsNdyo9XwL/B3rot7qdKSzkMYvFRIHYH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mZXWL/btsNdyo9XwL/B3rot7qdKSzkMYvFRIHYH1/img.png&quot; data-alt=&quot;초록색 박스의 비트를 통해서만 인덱스 환산&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mZXWL/btsNdyo9XwL/B3rot7qdKSzkMYvFRIHYH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmZXWL%2FbtsNdyo9XwL%2FB3rot7qdKSzkMYvFRIHYH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;175&quot; height=&quot;141&quot; data-origin-width=&quot;175&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;초록색 박스의 비트를 통해서만 인덱스 환산&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 함수가 32비트 영역을 고르게 사용하도록 만들었다고 해도 해시 값을 2의 승수로 나누면 해시 충돌이 쉽게 발생하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 이유 때문에 Java에서는 &lt;b&gt;보조 해시 함수&lt;/b&gt;를 사용하게 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;보조 해시 함수&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보조 해시 함수는 &lt;b&gt;객체 해시 코드의 상위 16비트 값을 해시코드와 XOR 연산&lt;/b&gt;을 해주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보조 해시 함수는 Java 1.4에 등장하여 Java 5 ~ Java 7까지 같은 방식을 사용하다가 Java 8부터 이전 버전에서 사용하던 것보다 단순한 새로운 방식의 보조 해시 함수를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 Java 8부터 버킷의 데이터가 많을 경우 레드-블랙 트리를 사용하기 때문에 성능 문제가 완화된 것과 해시 함수 자체가 균등 분포가 잘되게 만들어져 이전 버전에 사용하던 방식이 효과가 크지 않기 때문이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;인덱스를 반환할 때 HashCode % 버킷 개수 로 연산하는 것이 맞지만 버킷의 개수가 2의 제곱으로 증가할 때는 해시 코드의 하위 x개의 비트만 사용하는 것과 값이 같기 때문에 나머지 연산 대신 HashCode &amp;amp; (버킷의 개수 - 1) 연산을 사용하는 것이 성능상 이점이 있다.&lt;br /&gt;Java에서는 보조 해시 함수를 통해 hashcode를 생성한 이후에 HashCode &amp;amp; (버킷의 개수 - 1) 연산을 하게 된다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Java에서 Hash를 많이 사용하는 이유&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Java는 객체지향 언어이기 때문에 단순히 배열에 데이터를 저장하기 보다는 key-value 구조로 다루는 일이 많으며, 이때 가장 직관적인 자료구조가 Map이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Hash를 사용하게 되면 데이터의 검색, 삽입, 삭제 속도가 빠르기 때문에 HashMap을 자주 사용하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Java의 컬렉션 프레임워크가 Hash 기반 구조를 기본으로 제공한다.&lt;/li&gt;
&lt;li&gt;Java의 모든 객체의 부모는 Object로 hashCode()와 equals() 메서드를 제공한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이런 구조 덕분에 Java에서는 Hash 관련 자료구조를 범용적으로 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;C나 C++처럼 해시 함수를 따로 만들어주지 않아도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Java는 해시 기반 자료 구조를 계속해서 튜닝하여 성능 최적화를 해왔다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/ZBu_slSH5Sk?feature=shared&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/ZBu_slSH5Sk?feature=shared&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://d2.naver.com/helloworld/831311&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://d2.naver.com/helloworld/831311&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/Java</category>
      <category>Hash</category>
      <category>java</category>
      <category>해시</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/23</guid>
      <comments>https://immigrationssu.tistory.com/entry/Java-Java%EC%97%90%EC%84%9C-Hash%EB%A5%BC-%EB%A7%8E%EC%9D%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0#entry23comment</comments>
      <pubDate>Wed, 9 Apr 2025 16:33:51 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 메모리 구조로 알아보는 JVM</title>
      <link>https://immigrationssu.tistory.com/entry/Java-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-JVM</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Runtime Data Area&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpVYos/btsM67ZqUv4/SJgxK9ATSWrarWfOL0bgAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpVYos/btsM67ZqUv4/SJgxK9ATSWrarWfOL0bgAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpVYos/btsM67ZqUv4/SJgxK9ATSWrarWfOL0bgAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpVYos%2FbtsM67ZqUv4%2FSJgxK9ATSWrarWfOL0bgAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1108&quot; height=&quot;560&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Runtime Data Area는 JVM의 메모리 구조를 의미하며 총 5가지 영역으로 구분됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Thread가 모두 공유하는 영역
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Method Area&lt;/li&gt;
&lt;li&gt;Heap&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Thread가 독립적으로 사용하는 영역
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Stack&lt;/li&gt;
&lt;li&gt;PC Register&lt;/li&gt;
&lt;li&gt;Native Method Stack&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Method Area&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java 파일은 Java 컴파일러에 의해 JVM에서 읽을 수 있도록 Java Bytecode로 변환하여 class 파일을 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 생성된 class 파일은 JVM의 Class Loader에 의해서 JVM 메모리 영역에 클래스 정보를 올리게 되는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 클래스 정보가 올려지는 곳이 &lt;b&gt;Method Area&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Method Area는 크게 아래와 같은 정보를 담고 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스 구조 정보&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스명, 패키지명, 부모 클래스 정보 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Runtime Constant Pool
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리터럴, 심볼 참조(메서드, 필드, 클래스)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;필드 정보&lt;/li&gt;
&lt;li&gt;메서드 정보&lt;/li&gt;
&lt;li&gt;메서드의 바이트코드&lt;/li&gt;
&lt;li&gt;static 변수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 java 코드를 컴파일하여 Method Area 영역에 올라가는 예시를 보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1743733688304&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Example {
    public static final String GREETING = &quot;Hello, JVM!&quot;;
    private int number;

    public Example(int number) {
        this.number = number;
    }

    public void printGreeting() {
        System.out.println(GREETING + &quot; Your number is: &quot; + number);
    }

    public static void main(String[] args) {
        Example ex = new Example(42);
        ex.printGreeting();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEcaWJ/btsM9a1I3Sl/4rvfgdwParS6yANRY3k8A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEcaWJ/btsM9a1I3Sl/4rvfgdwParS6yANRY3k8A1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEcaWJ/btsM9a1I3Sl/4rvfgdwParS6yANRY3k8A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEcaWJ%2FbtsM9a1I3Sl%2F4rvfgdwParS6yANRY3k8A1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1036&quot; height=&quot;613&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Example.java 코드를 실행시키게 되면 위와 같이 Method Area 영역에 클래스 정보가 올라가게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Main 메서드 실행시 Thread가 생성되며 해당 Thread는 Method Area에서 Example 클래스 정보를 참조하여 프로그램을 실행시키게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgKOoT/btsM8g24QdF/C08BjF0vPZoJsIymFC0nX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgKOoT/btsM8g24QdF/C08BjF0vPZoJsIymFC0nX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgKOoT/btsM8g24QdF/C08BjF0vPZoJsIymFC0nX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgKOoT%2FbtsM8g24QdF%2FC08BjF0vPZoJsIymFC0nX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;783&quot; height=&quot;564&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The Java Virtual Machine Specification(2.5.4)&lt;/a&gt; 에서는 Method Area를 Heap의 한 부분으로 기술하지만 Heap과 구분하기 위해 &lt;b&gt;Non-Heap&lt;/b&gt;이라고 부르기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM 명세에서는 특정 방식을 강제하지 않아 벤더사가 구현 방식을 정하면 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hotspot VM 개발팀은 Permanent&amp;nbsp;Generation을 구현하여 GC의 수집 범위를 Method Area까지 확장하기로 결정했고 Java 7 이전에는 Method Area를 Permanent&amp;nbsp;Generation에 구현하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;(참고로 다른 VM은 Permanent&amp;nbsp;Generation라는 개념이 없었습니다. ex-BEA JRockit, IBM j9)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Permanent&amp;nbsp;Generation은 JVM 시작시 크기가 고정되어 클래스가 많이 로드되면 OOM이 발생하였습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;OutOfMemoryError: PermGen space&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 7에서는 이와 같은 문제를 개선하고자 Permanent&amp;nbsp;Generation(Method Area)에서 관리하던 문자열 상수와 정적 변수등의 정보를 Heap으로 옮겼고, Java 8부터는 Permanent Generation 개념을 지우고 Permanent&amp;nbsp;Generation에 남아있던 모든 정보를 네이티브 메모리에 구현한 Metaspace로 옮겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네이티브 메모리에 구현함으로써 OS 메모리만큼 자동으로 확장이 가능하기에 크기가 고정되었던 문제를 해결할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Heap&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Heap은 인스턴스 객체와 배열이 저장되는 영역으로 GC의 대상이 되는 영역입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Method Area와 마찬가지로 모든 Thread가 공유하는 영역으로 동시성 이슈가 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Heap의 생성된 인스턴스의 참조값은 Stack, Native Method Stack, 상수 풀등에 저장됩니다. (Root Space)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Heap 영역이 가득차게 되면 OutOfMemoryError가 발생하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상기에 기술하였듯이 JVM의 상세한 구현은 벤더들에게 일임되어 있어 GC뿐만 아니라 Heap의 전반적인 구성도 특별히 정의된바 없이 JVM을 구현하는 벤더에게 전권을 위임하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;(대체로 Hotspot VM이 많이 사용되고 있습니다.)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GC는 세대 단위 컬렉션 이론에 기초해 설계되었습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #f8f9fa; color: #212529; text-align: start;&quot;&gt;약한 세대 가설 : 대다수 객체는 일찍 죽는다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f8f9fa; color: #212529; text-align: start;&quot;&gt;강한 세대 가설 : 가비지 컬렉션 과정에서 살아남은 횟수가 늘어날수록 더 오래 살 가능성이 커진다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f8f9fa; color: #212529; text-align: start;&quot;&gt;세대 간 참조 가설 : 세대 간 참조의 개수는 같은 세대 안에서의 참조보다 훨씬 적다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 이론에 기반하여 Heap 영역을 나누게 되었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sD2bG/btsM9zfZNya/AjQAsEefhUr7q6NgyegRKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sD2bG/btsM9zfZNya/AjQAsEefhUr7q6NgyegRKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sD2bG/btsM9zfZNya/AjQAsEefhUr7q6NgyegRKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsD2bG%2FbtsM9zfZNya%2FAjQAsEefhUr7q6NgyegRKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1034&quot; height=&quot;424&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Young Generation&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로 생성된 객체가 저장되는 공간&lt;/li&gt;
&lt;li&gt;GC가 가장 자주 발생하는 영역(Minor GC)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Eden&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체가 처음 생성될 때 저장되는 공간&lt;/li&gt;
&lt;li&gt;대부분의 객체가 짧은 생명주기를 가지므로 빠르게 GC 대상이 됩니다.&lt;/li&gt;
&lt;li&gt;Eden 영역이 꽉 차게 되면 Minor GC가 실행되어 참조가 살아있는 객체는 Survivor(S0 or S1) 영역으로 이동하게 되고 남은 객체는 모두 제거하게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Survivor&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Eden 영역에서 살아남은 객체가 이동하는 공간&lt;/li&gt;
&lt;li&gt;한 Survivor 영역이 가득 차면 다른 Survivor 영역으로 복사하고 이전 Survivor는 비우게 됩니다.&lt;/li&gt;
&lt;li&gt;일정 횟수 이상 참조되어 기준 Age를 넘기면 Old Generation으로 이동하게 됩니다.(Promotion)&lt;/li&gt;
&lt;li&gt;Survivor 영역 중 하나는 반드시 비어 있어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Old Generation&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Young Gen에서 살아남은 객체들이 이동하는 공간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체 크기가 크거나 Survivor 영역의 메모리가 부족할 경우 Eden 영역에서 바로 이동할 수도 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;객체의 생명주기가 긴 경우 해당 영역으로 이동하게 됩니다.&lt;/li&gt;
&lt;li&gt;Old Gen에 객체가 가득 차게 되면 Full GC가 실행됩니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Full GC가 실행하게 되면 GC를 수행하는 Thread를 제외한 모든 Thread가 멈추게 됩니다. -&amp;gt; 이를 stop-the-world라고 합니다.&lt;/li&gt;
&lt;li&gt;Full GC는 Minor GC보다 느리며 시스템 성능에 영향을 줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Old Gen에는 카드 테이블이 존재합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Old Gen에 있는 객체가 Young Gen의 객체를 참조할 때마다 정보가 표시되어 Young Gen의 Minor GC가 실행될 때 Old Gen에 있는 모든 객체의 참조를 확인하지 않고 카드 테이블만 확인하여 GC대상을 식별합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하지만 위 영역은 G1 GC가 등장하면서 Region이라는 단위로 나뉘어지게 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Region 별로 Eden, Survivor, Old등 동적으로 세대를 관리합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Stack&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지역변수, 메소드의 매개변수, 리턴 값 등 임시적으로 사용되는 값들이 저장되는 영역으로 PC Register, Native Method Stack과 함께 Thread가 생성될 때마다 독립적으로 할당됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;619&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI6aJj/btsM8cmhLPP/u9N5XORDn0A0U1lK9K9kAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI6aJj/btsM8cmhLPP/u9N5XORDn0A0U1lK9K9kAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI6aJj/btsM8cmhLPP/u9N5XORDn0A0U1lK9K9kAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI6aJj%2FbtsM8cmhLPP%2Fu9N5XORDn0A0U1lK9K9kAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1142&quot; height=&quot;619&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;619&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stack은 메서드 호출시 생성되는 프레임과 지역 변수 및 메서드 호출에 필요한 정보를 저장하는데 사용 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thread가 메서드 호출시 프레임이 Push되고 메서드 실행이 끝나면 Pop이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드 호출이 너무 깊거나 무한 재귀 호출이 일어날 경우 스택의 크기를 초과하여 StackOverFlowError가 발생할 수 있고 Thread 생성시 Stack에 할당할 메모리가 부족하게 되면 OOM이 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;(해당 내용 관련해서 실제로 OOM이 발생했던 경험을 포스팅한 적이 있으니 참고해주세요! - &lt;a href=&quot;https://immigrationssu.tistory.com/entry/Spring-Boot-AWS-Opensearch%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8B%A4-OOM%EC%9D%84-%EB%A7%8C%EB%82%98%EB%8B%A4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xs54c/btsM9XOxdLD/oR8aZ7dyDs74JtcqZqmaG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xs54c/btsM9XOxdLD/oR8aZ7dyDs74JtcqZqmaG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xs54c/btsM9XOxdLD/oR8aZ7dyDs74JtcqZqmaG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxs54c%2FbtsM9XOxdLD%2FoR8aZ7dyDs74JtcqZqmaG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1262&quot; height=&quot;710&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stack 프레임의 구조는 위 그림을 참고해주세요&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Local Variable Array
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메서드 내에서 선언된 변수나 파라미터 정보를 해당 영역에 저장합니다.&lt;/li&gt;
&lt;li&gt;지역 변수는 기본 타입의 값(상수 풀)이나 객체에 대한 Refernece(Heap)가 될 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Operand Stack
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;연산을 위한 임시 공간으로 계산을 할때 필요할 수 있는 값들이 임시로 저장됩니다.&lt;/li&gt;
&lt;li&gt;메서드 실행 도중 연산을 위해 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Current Class Constant Pool Reference
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Method Area의 Runtime Constant Pool에 대한 참조입니다.&lt;/li&gt;
&lt;li&gt;메서드가 속한 클래스의 상수를 사용하기 위해 RCP에 대한 참조값을 가지게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;PC Register&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stack과 Native Method Stack과 함께 Thread가 생성될 때 각 Thread마다 할당되는 영역으로 현재 수행중인 JVM의 명령어 주소를 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;현재 실행중인 Thread의 바이트코드 줄 번호 표시기&lt;/b&gt;라고 생각하면 쉽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM의 명령어 해석(인터프리팅) 과정에서 필수적인 역할을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Thread마다 독립적인 PC Register를 유지하여 멀티스레드 환경에서도 독립적으로 명령어를 실행시킬 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thread가 컨텍스트 스위칭될 때 해당 Thread의 PC Register 값도 저장되고 복원됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림을 참고하면 PC Register가 어떤 역할을 하는지 이해할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcIcEC/btsM9E2Ng9B/jbsXKR4vqMSQZvL5g41nX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcIcEC/btsM9E2Ng9B/jbsXKR4vqMSQZvL5g41nX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcIcEC/btsM9E2Ng9B/jbsXKR4vqMSQZvL5g41nX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcIcEC%2FbtsM9E2Ng9B%2FjbsXKR4vqMSQZvL5g41nX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1261&quot; height=&quot;696&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Native Method Stack&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM이 Java 프로그램에서 네이티브 메서드를 실행할 때 사용하는 스택 영역으로 C, C++ 등으로 작성된 네이티브 코드를 실행할 때 필요하며 JNI(Java Native Interface)를 통해 네이티브 코드를 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM은 내부에 많은 OS의 네티이브 라이브러리를 사용하여 구현되는데 JVM 자체적으로 실행할 수 없으며 OS의 네이티브 API를 호출해야 합니다. 이때 Native Method Stack이 필요합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;파일 시스템 접근(File I/O), 네트워크 통신(Sockets, HTTP requests), Thread 관리, 메모리 관리 등등&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 메서드를 실행할 때는 PC Register가 바이트코드의 주소를 저장하지만 Native 메서드가 실행될 때는 PC Register의 값이 특정한 주소를 가리키지 않으며 Undefined 상태가 되고 이에 대한 처리는 Native Method Stack에서 담당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stack 영역과 마찬가지로 크기를 초과하면 StackOverflowError가 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;참고&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@impala/JAVA-JVM-Runtime-Data-Area&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@impala/JAVA-JVM-Runtime-Data-Area&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/GU254H0N93Y?feature=shared&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/GU254H0N93Y?feature=shared&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dzone.com/articles/java-memory-architecture-model-garbage-collection&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dzone.com/articles/java-memory-architecture-model-garbage-collection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://product.kyobobook.co.kr/detail/S000213057051&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;JVM 밑바닥까지 파헤치기&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1743745900409&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Java Memory Architecture Cheat Sheet&quot; data-og-description=&quot; &quot; data-og-host=&quot;dzone.com&quot; data-og-source-url=&quot;https://dzone.com/articles/java-memory-architecture-model-garbage-collection&quot; data-og-url=&quot;https://dzone.com/articles/java-memory-architecture-model-garbage-collection&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cDDHbN/hyYxC1pk3Q/fkpFEm5sX30ngDkUZSAqR0/img.jpg?width=640&amp;amp;height=400&amp;amp;face=0_0_640_400,https://scrap.kakaocdn.net/dn/fVIVR/hyYyLczVdX/Dqit0FEf6lQJq2bdQofzK0/img.jpg?width=640&amp;amp;height=400&amp;amp;face=0_0_640_400,https://scrap.kakaocdn.net/dn/bo3G49/hyYA3JP2gN/M3RGvnmEKC8w2xqXVRqjL1/img.jpg?width=704&amp;amp;height=730&amp;amp;face=0_0_704_730&quot;&gt;&lt;a href=&quot;https://dzone.com/articles/java-memory-architecture-model-garbage-collection&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dzone.com/articles/java-memory-architecture-model-garbage-collection&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cDDHbN/hyYxC1pk3Q/fkpFEm5sX30ngDkUZSAqR0/img.jpg?width=640&amp;amp;height=400&amp;amp;face=0_0_640_400,https://scrap.kakaocdn.net/dn/fVIVR/hyYyLczVdX/Dqit0FEf6lQJq2bdQofzK0/img.jpg?width=640&amp;amp;height=400&amp;amp;face=0_0_640_400,https://scrap.kakaocdn.net/dn/bo3G49/hyYA3JP2gN/M3RGvnmEKC8w2xqXVRqjL1/img.jpg?width=704&amp;amp;height=730&amp;amp;face=0_0_704_730');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Java Memory Architecture Cheat Sheet&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dzone.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1743745860853&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;JVM 밑바닥까지 파헤치기 | 저우즈밍 - 교보문고&quot; data-og-description=&quot;JVM 밑바닥까지 파헤치기 | 자바 가상 머신의 깊숙한 내부를 향해 떠나는 흥미진진한 모험C&amp;middot;C++를 사용해 주로 프로그래밍을 하던 시절 까다로운 메모리 관리와 플랫폼 이식성 문제는 개발자들에&quot; data-og-host=&quot;product.kyobobook.co.kr&quot; data-og-source-url=&quot;https://product.kyobobook.co.kr/detail/S000213057051&quot; data-og-url=&quot;https://product.kyobobook.co.kr/detail/S000213057051&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eSgQW/hyYB93U4Pa/gc6PGkwCqzkLVKQAEZkOU1/img.jpg?width=458&amp;amp;height=599&amp;amp;face=0_0_458_599,https://scrap.kakaocdn.net/dn/bfmEwg/hyYCczziyu/pa8uUQzz6wBhTOAFxRqat1/img.jpg?width=458&amp;amp;height=599&amp;amp;face=0_0_458_599,https://scrap.kakaocdn.net/dn/bwaXLg/hyYyKLutop/W7Tf7nr7Vr2l2TKEmKBff1/img.png?width=335&amp;amp;height=335&amp;amp;face=0_0_335_335&quot;&gt;&lt;a href=&quot;https://product.kyobobook.co.kr/detail/S000213057051&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://product.kyobobook.co.kr/detail/S000213057051&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eSgQW/hyYB93U4Pa/gc6PGkwCqzkLVKQAEZkOU1/img.jpg?width=458&amp;amp;height=599&amp;amp;face=0_0_458_599,https://scrap.kakaocdn.net/dn/bfmEwg/hyYCczziyu/pa8uUQzz6wBhTOAFxRqat1/img.jpg?width=458&amp;amp;height=599&amp;amp;face=0_0_458_599,https://scrap.kakaocdn.net/dn/bwaXLg/hyYyKLutop/W7Tf7nr7Vr2l2TKEmKBff1/img.png?width=335&amp;amp;height=335&amp;amp;face=0_0_335_335');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JVM 밑바닥까지 파헤치기 | 저우즈밍 - 교보문고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;JVM 밑바닥까지 파헤치기 | 자바 가상 머신의 깊숙한 내부를 향해 떠나는 흥미진진한 모험C&amp;middot;C++를 사용해 주로 프로그래밍을 하던 시절 까다로운 메모리 관리와 플랫폼 이식성 문제는 개발자들에&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;product.kyobobook.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/Java</category>
      <category>java</category>
      <category>jvm</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/22</guid>
      <comments>https://immigrationssu.tistory.com/entry/Java-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-JVM#entry22comment</comments>
      <pubDate>Fri, 4 Apr 2025 14:54:30 +0900</pubDate>
    </item>
    <item>
      <title>[요약] 멀티 코어를 100% 활용하는 자바 병렬 프로그래밍</title>
      <link>https://immigrationssu.tistory.com/entry/%EC%9A%94%EC%95%BD-%EB%A9%80%ED%8B%B0-%EC%BD%94%EC%96%B4%EB%A5%BC-100-%ED%99%9C%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9E%90%EB%B0%94-%EB%B3%91%EB%A0%AC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;9788960770485.jpg&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm0wUw/btsMUYIyHJG/d0E4X9NA366kRkjvwdSSb0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm0wUw/btsMUYIyHJG/d0E4X9NA366kRkjvwdSSb0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm0wUw/btsMUYIyHJG/d0E4X9NA366kRkjvwdSSb0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm0wUw%2FbtsMUYIyHJG%2Fd0E4X9NA366kRkjvwdSSb0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;324&quot; height=&quot;431&quot; data-filename=&quot;9788960770485.jpg&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;리뷰&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금이라도 읽게 돼서 다행이라고 느껴질 정도로 매우 깊은 내용이 담겨있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평소에 Thread, ExecutorService를 사용할 줄만 알았지 현재 내가 짠 코드가 스레드 세잎한 상태인지 아닌지도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몰랐던 지난날이 부끄럽다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책이 출판한지 오래 되어 Java 5, 6을 기준으로 다루긴 하지만 버전과 상관없이 읽기 무방하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;500p가 넘고 깊이 있는 내용을 다루기 때문에 책이 다소 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책에서도 예제 코드와 그림이 상세하게 나와있으나 그럼에도 이해가 되지 않는 부분이 나올 때마다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ChatGPT의 도움을 받아서 예제 코드를 보며 이해를 하곤 했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1부 기본원리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태 없는 객체는 항상 스레드 안전하다.&lt;/li&gt;
&lt;li&gt;암묵적인 락은 재진입이 가능하기 때문에 특정 스레드 본인이 이미 획득한 락을 다시 확보할 수 있다.&lt;/li&gt;
&lt;li&gt;여러 변수에 대한 불변조건이 있으면 해당 변수들은 모두 같은 락으로 보호해야 한다.&lt;/li&gt;
&lt;li&gt;복잡하고 오래 걸리는 계산 작업, 네트워크 작업, 사용자 입출력 작업과 같이 빨리 끝나지 않을 수 있는 작업을 하는 부분에서는 가능한 락을 잡지 말아야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;객체 공유&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;가시성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동기화 되지 않은 상황에서 메모리상의 변수를 대상으로 작성해둔 코드가 반드시 이런 순섯로 동작할 것이다라고 단정지을 수 없다.&lt;/li&gt;
&lt;li&gt;락은 상호 배제뿐만 아니라 정상적인 메모리 가시성을 확보하기 위해 사용한다. 각 스레드에서 각자 최신의 정상적인 값으로 활용하려면 동일한 락을 사용해 모두 동기화시켜야 한다.&lt;/li&gt;
&lt;li&gt;동기화하고자 하는 부분을 명확하게 볼 수 있고 구혀녀하기가 훨씬 간단한 경우에만 volatile 변수를 활용하자, 반대로 작은 부분이라도 가시성을 추론해봐야 하는 경우에는 volatile 변수를 사용하지 않는 것이 좋다.&lt;/li&gt;
&lt;li&gt;락을 사용하면 가시성과 연산의 단일성을 모두 보장받지만 volatile 변수는 연산의 단일성을 보장하지 못한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;공개와 유출&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성&amp;nbsp;메소드를&amp;nbsp;실행하는&amp;nbsp;도중에는&amp;nbsp;this&amp;nbsp;변수가&amp;nbsp;외부에&amp;nbsp;유출되지&amp;nbsp;않게&amp;nbsp;해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;스레드 한정&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 객체를 단일 스레드에서만 활용한다고 확신할 수 있다면 해당 객체는 따로 동기화할 필요가 없다&lt;/li&gt;
&lt;li&gt;ThreadLocal을 통해 스레드 한정을 형식적으로 구현할 수 있다. ex) JDBC Connection 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;불변성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체를 동기화하지 않고도 안전하게 사용할 수 있는 방법&lt;/li&gt;
&lt;li&gt;불변&amp;nbsp;&amp;nbsp;객체는 언제라도 스레드에 안전하다.&lt;/li&gt;
&lt;li&gt;불변 객체는 다음 조건을 만족해야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성되고 난 이후에는 객체의 상태를 변경할 수 없다&lt;/li&gt;
&lt;li&gt;내부의 모든 변수는 final로 설정돼야 한다.&lt;/li&gt;
&lt;li&gt;적절한 방법으로 생성 돼야 한다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex) this 변수에 대한 참조가 외부로 유출되지 않아야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;안전&amp;nbsp;공개&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;불변 객체는 별다른 동기화 방법을 적용하지 않았다 해도 어느 스레드에서건 마음껏 안전하게 사용할 수 있다. 불변 객체를 공개하는 부분에 동기화 처리를 하지 않았다 해도 아무런 문제가 없다.&lt;/li&gt;
&lt;li&gt;객체를 안전하게 공개하려면 해당 객체에 대한 참조와 객체 내부의 상태를 외부의 스레드에게 동시에 볼 수 있어야 한다. 올바르게 생성 메소드가 실행되고 난 객체는 다음과 같은 방법으로 안전하게 공개할 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체에 대한 참조를 static 메소드에서 초기화시킨다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JVM에서 클래스를 초기화하는 시점에 작업이 모두 진행된다.&lt;/li&gt;
&lt;li&gt;그런데 JVM 내부에서 동기화가 맞춰져 있기 떄문에 객체를 안전하게 공개할 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;객체에 대한 참조를 volatile 변수 또는 AtomicReference 클래스에 보관한다.&lt;/li&gt;
&lt;li&gt;객체에 대한 참조를 올바르게 생성된 클래스 내부의 final 변수에 보관한다.&lt;/li&gt;
&lt;li&gt;락을 사용해 올바르게 막혀있는 변수에 객체에 대한 참조를 보관한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;안전하게&amp;nbsp;공개한&amp;nbsp;결과적인&amp;nbsp;불변&amp;nbsp;객체는&amp;nbsp;별다른&amp;nbsp;동기화&amp;nbsp;작업&amp;nbsp;없이도&amp;nbsp;여러&amp;nbsp;스레드에서&amp;nbsp;안전하게&amp;nbsp;호출해&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스레드&amp;nbsp;안전한&amp;nbsp;컬렉션에&amp;nbsp;변경&amp;nbsp;가능한&amp;nbsp;객체를&amp;nbsp;가지고&amp;nbsp;있더라도&amp;nbsp;해당&amp;nbsp;객체를&amp;nbsp;변경하지&amp;nbsp;않는다면&amp;nbsp;동기화&amp;nbsp;코드를&amp;nbsp;만들&amp;nbsp;필요가&amp;nbsp;없다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;가변 객체를 사용할 때에는 공개하는 부분과 가변 객체를 사용하는 모든 부분에서 동기화 코드를 작성해야만 한다.&lt;/li&gt;
&lt;li&gt;객체를 사용하기 전에 동기화 코드를 적용해 락을 확보해야하는지, 객체 내부의 값을 바꿔도 괜찮은지, 값을 읽기만 해야하는 것인지등 정확하게 알고 있어야 한다.&lt;/li&gt;
&lt;li&gt;반대로 객체를 외부에서 사용할 수 있도록 공개할 때에는 해당 객체를 어떤 방법으로 사용할 수 있고 사용해야 하는지에 대해서 정확하게 설명해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정리&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체를&amp;nbsp;공유해&amp;nbsp;사용하고자&amp;nbsp;할&amp;nbsp;때&amp;nbsp;가장&amp;nbsp;많이&amp;nbsp;사용되는&amp;nbsp;원칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스레드 한정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스레드에&amp;nbsp;한정된&amp;nbsp;객체는&amp;nbsp;완전하게&amp;nbsp;해당&amp;nbsp;스레드&amp;nbsp;내부에&amp;nbsp;존재하면서&amp;nbsp;그&amp;nbsp;스레드에서만&amp;nbsp;호출해&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;읽기&amp;nbsp;전용&amp;nbsp;객체를&amp;nbsp;공유
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;읽기&amp;nbsp;전용이기&amp;nbsp;때문에&amp;nbsp;값이&amp;nbsp;변경될&amp;nbsp;수&amp;nbsp;없고&amp;nbsp;불변&amp;nbsp;객체와&amp;nbsp;결과적으로&amp;nbsp;불변인&amp;nbsp;객체가&amp;nbsp;읽기&amp;nbsp;전용&amp;nbsp;객체에&amp;nbsp;해당된다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;스레드에&amp;nbsp;안전한&amp;nbsp;객체를&amp;nbsp;공유
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스레드에&amp;nbsp;안전한&amp;nbsp;컬렉션&amp;nbsp;등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;동기화&amp;nbsp;방법&amp;nbsp;적용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지정한&amp;nbsp;락을&amp;nbsp;획득하기&amp;nbsp;전에는&amp;nbsp;해당&amp;nbsp;객체를&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;없다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;객체&amp;nbsp;구성&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스레드 안전한 클래스 설계&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스가&amp;nbsp;스레드&amp;nbsp;안정성을&amp;nbsp;확보하도록&amp;nbsp;설계하고자&amp;nbsp;할때&amp;nbsp;고려사항
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체의 상태를 보관하는 변수가 어떤 것인가&lt;/li&gt;
&lt;li&gt;객체의 상태를 보관하는 변수가 가질 수 있는 값이 어떤 종류, 어떤 범위에 해당하는가&lt;/li&gt;
&lt;li&gt;객체 내부의 값을 동시에 사용하고자 할 때 그 과정을 관리할 수 있는 정책&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;객체가&amp;nbsp;가질&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;값의&amp;nbsp;범위와&amp;nbsp;변동&amp;nbsp;폭을&amp;nbsp;정확하게&amp;nbsp;인식하지&amp;nbsp;못한다면,&amp;nbsp;스레드&amp;nbsp;안정성을&amp;nbsp;완벽하게&amp;nbsp;확보할&amp;nbsp;수&amp;nbsp;없다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인스턴스 한정&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 객체 내부에 숨겨두면 숨겨진 내용은 해당 객체의 메소드에서만 사용할 수 있기 때문에 숨겨진 데이터를 사용하고자 할 때에는 항상 지정된 형태의 락이 적용되는지 쉽고 정확하게 파악할 수 있다&lt;/li&gt;
&lt;li&gt;인스턴스 한정 기법을 사용하면 전체 프로그램을 다 뒤져보지 않고도 스레드 안정성을 확보하고 있는지 쉽게 분석해 볼수 있기 때문에 스레드에 안전한 객체를 좀 더 쉽게 구현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;스레드 안정성 위임&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스에 두 개 이상의 변수를 사용하는 복합 연산 메소드를 갖고 있다면 위임 기법만으로는 스레드 안정성을 확볼할 수 없다&lt;/li&gt;
&lt;li&gt;이런 경우에는 내부적으로 락을 활용해서 복합 연산이 단일 연산으로 처리되도록 동기화해야한다.&lt;/li&gt;
&lt;li&gt;클래스가 서로 의존성 없이 독립적이고 스레드 안전한 두 개 이상의 클래스를 조합해 만들어져 있고 두 개 이상의 클래스를 한번에 처리하는 복합 연산 메소드가 없는 상태라면, 스레드 안정성을 내부 변수에게 모두 위임할 수 있다.&lt;/li&gt;
&lt;li&gt;상태 변수가 스레드 안전하고 클래스 내부에서 상태 변수의 값에 대한 의존성을 갖고 있지 않고, 상태 변수에 대한 어떤 연산을 수행하더라도 잘못된 상태에 이를 가능성이 없다면, 해당 변수는 외부에 공개해도 안전하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;스레드&amp;nbsp;안전하게&amp;nbsp;구현된&amp;nbsp;클래스에&amp;nbsp;기능&amp;nbsp;추가&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자바&amp;nbsp;모니터&amp;nbsp;패턴을&amp;nbsp;활용해&amp;nbsp;새로운&amp;nbsp;클래스&amp;nbsp;내부에&amp;nbsp;캡슐화하고&amp;nbsp;해당&amp;nbsp;클래스에&amp;nbsp;들어&amp;nbsp;있는&amp;nbsp;스레드&amp;nbsp;안전한&amp;nbsp;클래스가&amp;nbsp;외부로&amp;nbsp;공개되지&amp;nbsp;않는&amp;nbsp;한&amp;nbsp;스레드&amp;nbsp;안정성을&amp;nbsp;확보하면서&amp;nbsp;기능을&amp;nbsp;추가할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동기화&amp;nbsp;정책&amp;nbsp;문서화하기&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구현한&amp;nbsp;클래스가&amp;nbsp;어느&amp;nbsp;수준까지&amp;nbsp;스레드&amp;nbsp;안전성을&amp;nbsp;보장하는지에&amp;nbsp;대해&amp;nbsp;충분히&amp;nbsp;문서를&amp;nbsp;작성해둬야&amp;nbsp;한다.&amp;nbsp;동기화&amp;nbsp;기법이나&amp;nbsp;정책을&amp;nbsp;잘&amp;nbsp;정리해두면&amp;nbsp;유지보수&amp;nbsp;팀이&amp;nbsp;원활하게&amp;nbsp;관리할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구성 단위&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동기화된 컬렉션 클래스&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동기화된 컬렉션 클래스는 대부분 클라이언트 측 락을 사용할 수 있도록 만들어져 있기 때문에 컬렉션 클래스가 사용하는 락을 함께 사용한다면 새로 추가하는 기능을 컬렉션 클래스에 들어있는 다른 메소드와 같은 수준으로 동기화 시킬 수 있다.&lt;/li&gt;
&lt;li&gt;반복문에 락을 걸어두게 되면 성능 저하가 발생하며 컬렉션의 수정을 감지할 경우 Exception이 발생한다.&lt;/li&gt;
&lt;li&gt;클래스 내부에서 필요한 변수를 모두 캡슐화하면 그 상태를 보존하기가 훨씬 편리한 것처럼 동기화 기법을 클래스 내부에 캡슐화하면 동기화 정책을 적용하기가 쉽다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;병렬 컬렉션&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존에&amp;nbsp;사용하던&amp;nbsp;동기화&amp;nbsp;컬렉션&amp;nbsp;클래스를&amp;nbsp;병렬&amp;nbsp;컬렉션으로&amp;nbsp;교체하는&amp;nbsp;것만으로도&amp;nbsp;별다른&amp;nbsp;위험&amp;nbsp;요소&amp;nbsp;없이&amp;nbsp;전체적인&amp;nbsp;성능을&amp;nbsp;상당히&amp;nbsp;끌어&amp;nbsp;올릴&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;블로킹&amp;nbsp;큐와&amp;nbsp;프로듀서-컨슈머&amp;nbsp;패턴&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;블로킹&amp;nbsp;큐는&amp;nbsp;애플리케이션이&amp;nbsp;안정적으로&amp;nbsp;동작하도록&amp;nbsp;만들고자&amp;nbsp;할&amp;nbsp;때&amp;nbsp;요긴하게&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;도구이다.&amp;nbsp;블로킹&amp;nbsp;큐를&amp;nbsp;사용하면&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;양보다&amp;nbsp;훨씬&amp;nbsp;많은&amp;nbsp;작업이&amp;nbsp;생겨&amp;nbsp;부하가&amp;nbsp;걸리는&amp;nbsp;상황에서&amp;nbsp;작업량을&amp;nbsp;조절해&amp;nbsp;애플리케이션이&amp;nbsp;안정적으로&amp;nbsp;동작하도록&amp;nbsp;유도할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동기화 클래스&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;래치는 특정한 단일 동작이 완료되기 이전에는 어떤 기능도 동작하지 않도로고 막아내야 하는 경우에 요긴하게 사용할 수 있다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 자원을 확보하기 전에는 작업을 시작하지 말아야 하는 경우&lt;/li&gt;
&lt;li&gt;의존성을 갖고있는 다른 서비스가 시작하기 전에는 특정 서비스가 실행되지 않도록 막아야 하는 경우&lt;/li&gt;
&lt;li&gt;특정 작업에 필요한 모든 객체가 실행할 준비를 갖출 땎가지 기다리는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FutureTask는 Executor 프레임워겡서 비동기적인 작업을 실행하고자 할 때 사용하며, 기타 시간이 많이 필요한 모든 작업이 있을 때 실제 결과가 필요한 시점 이전에 미리 작업을 실행시켜두는 용도로 사용한다.&lt;/li&gt;
&lt;li&gt;카운팅 세마포어는 특정 자원이나 특정 연산을 동시에 사용하거나 호출할 수 있는 스레드의 수를 제한하고자 할 떄 사용한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어떤 클래스라도 크기가 제한된 컬렉션 클래스로 활용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;배리어는 특정 이벤트가 발생할 때까지 여러 개의 스레드를 대기 상태로 잡아 둘 수 있다는 측면에서 래치와 비슷하다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;차이점은 모든 스레드가 배리어 위치에 동시에 이르러야 관문이 열리고 계속해서 실행할 수 있다는 점이다.&lt;/li&gt;
&lt;li&gt;래치는 이벤트를 기다리기 위한 동기화 클래스이고, 배리어는 다른 스레드를 기다리기 위한 동기화 클래스이다.&lt;/li&gt;
&lt;li&gt;배리어는 대부분 실제 작업은 모두 여러 스레드에서 병렬로 처리하고 담은 단계로 넘어가기 전에 이번 단계에서 계산해야할 내용을 모두 취합해야 하는 등의 작업이 많이 일어나는 시뮬레이션 알고리즘에서 유용하게 사용할 수 있다.(CyclicBarrier)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Exchanger는 두 개의 스레드가 연결되는 배리어이며, 배리어 포인트에 도달하면 양쪽의 스레드가 서로 갖고 있던 값을 교환한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;양쪽 스레드가 서로 대칭되는 작업을 수행할 때 유용하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;효율적이고 확장성있는 결과 캐시 구현&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HashMap을 통해 캐시를 구현한다고 했을 때 동시성을 고려해서 HashMap에 동시에 접근하지 못하도록 메소드 전체를 동기화 시킬 경우 캐시를 적용하니만 못하다 -&amp;gt; 성능이 떨어진다.&lt;/li&gt;
&lt;li&gt;HashMap 대신 ConcurrentHashMap을 사용하게 되면 성능상의 문제가 해소되지만 여러 스레드가 동시에 같은 값을 넘기면 같은 작업을 여러번 할 수 있다. 이럴 경우 FutureTask를 사용해서 작업이 진행되고 있다면 작업이 끝날때까지 대기해서 결과를 가져오거나 시작된 작업이 없다면 FutureTask를 만들어서 Map에 등록한다.&lt;/li&gt;
&lt;li&gt;하지만 그래도 Map에 결과를 추가할 때 단일 연산이 아니라 복합 연산을 사용하기 때문에 puIfAbsent라는 단일 연산 메소드를 사용해 결과를 저장하면 동시성을 확보하면서 성능도 확보한 캐시를 구현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1부 요약&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태가 바뀔 수 있다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;병렬성과 관련된 모든 문제점은 변경 가능한 변수에 접근하려는 시도를 적절하게 조율하는 것으로 해결 할 수 있다. 변경 가능성이 낮으면 낮을수록 스레드 안정성을 확보하기가 쉽다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;변경 가능한 값이 아닌 변수는 모두 final로 선언하라&lt;/li&gt;
&lt;li&gt;불변 객체는 항상 그 자체로 스레드 안전하다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;불변 객체는 간결하면서 안전하고 락이나 방어적 복사 과정을 거치지 않고도 얼마든지 공유해 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캡슐화하면 복잡도를 손쉽게 제어할 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 객체 내부에 캡슐화하면 값이 변경되는 자유도를 쉽게 제어할 수 있다. 객체 내부에서 동기화하는 기법을 캡슐화하면 동기화 정책을 손쉽게 적용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;변경 가능한 객체는 항상 락으로 막아줘야 한다.&lt;/li&gt;
&lt;li&gt;불변 조건 내부에 들어가는 모든 변수는 같은 락으로 막아줘야 한다.&lt;/li&gt;
&lt;li&gt;복합 연산을 처리하는 동안에는 항상 락을 확보하고 있어야 한다.&lt;/li&gt;
&lt;li&gt;여러 스레드에서 변경 가능한 변수의 값을 사용하도록 되어 있으면서 적절한 동기화 기법이 적용되지 않은 프로그램은 올바른 결과를 내놓지 못한다.&lt;/li&gt;
&lt;li&gt;동기화할 필요가 없는 부분에 대해서는 일부러 머리를 써서 고민할 필요가 없다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동기화 할 필요가 없다고 이래저래 추측한 결론에 의존해서는 안 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;설계 단계부터 스레드 안전성을 염두에 두고 있어야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아니면 최소환 결과물로 작성된 클래스가 스레드에 아전하지 않다고 반드시 문서로 남겨야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로그램 내부의 동기화 정책에 대한 문서를 남겨야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2부 병렬 프로그램 구조 잡기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;작업 실행&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스레드에서 작업 실행&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단일 스레드에서 작업을 순차적으로 실행한다면 높은 처리량과 빠른 반응 속도 모두를 충족하지 못한다.&lt;/li&gt;
&lt;li&gt;요청마다 스레드를 생성해서 작업을 처리하게 된다면 자원 낭비, 안정성 문제가 발생할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Executor&amp;nbsp;프레임웍&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 어디에서든 간에 `new Thread(runnable).start()` 와 같은 코드가 남아있다면 조만간 이런 부분에 유연한 실행 정책을 적용할 준비를 해야할 것이며, 나중을 위해서 Executor를 사용해 구현하는 방안을 심각하게 고려해봐야 한다.&lt;/li&gt;
&lt;li&gt;스레드풀을 사용하는 방법에는 많은 장점이 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매번 스레드를 생성하지 않고 재사용하기 때문에 여러 개의 요청을 처리하는데 필요한 리소스가 줄어드는 효과가 있다.&lt;/li&gt;
&lt;li&gt;이미 생성된 스레드가 대기하고 있다가 작업을 처리하기 때문에 딜레이가 발생하지 않아 전체적인 반응 속도도 향상된다.&lt;/li&gt;
&lt;li&gt;스레드 풀의 크기를 적절히 조절해두면 하드웨어 프로세서가 쉬지 않고 동작할 수 있으며 메모리를 전부 소모하거나 여러 스레드가 한정된 자원을 두고 서로 경쟁하느라 성능을 까먹는 현상도 없앨 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;병렬로&amp;nbsp;처리할&amp;nbsp;만한&amp;nbsp;작업&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유사한 작업 가운데 훨씬 세부적인 작업으로 병렬성을 높이지 못할 바에야, 이런 방법은 전체적인 성능을 떨어뜨리는 결과를 가져올 수 있다.&lt;/li&gt;
&lt;li&gt;다양한 종류의 작업을 여러 작업 스레드에서 나눠 처리하도록 할 때는 나눠진 작업이 일정한 크기를 유지하지 못할 수 있다는 단점도 있다.&lt;/li&gt;
&lt;li&gt;프로그램이 해야 할 일을 작은 작업으로 쪼개 실행할 때 실제적인 성능상의 이점을 얻으려면 프로그램이 하는 일을 대량의 동일한 작업으로 재정의해 병렬로 처리할 수 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;중단 및 종료&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;작업 중단&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API나 언어 명세 어디를 보더라도 인터럽트가 직압을 취소하는 과정에 어떤 역할을 하는지에 대해 명시되어 있는 부분은 없다. 하지만 실제 상황에서는 작업을 중단하고자 하는 부분이 아닌 다른 부분에 인터럽트를 사용한다면 오류가 발생하기 쉬울 수 밖에 없으며, 애플리케이션 규모가 커질수록 관리하기도 어려워진다.&lt;/li&gt;
&lt;li&gt;특정 스레드의 interrupt 메소드를 호출한다 해도 해당 스레드가 처리하던 작업을 멈추지는 않는다. 단지 해당 스레드에게 인터럽트 요청이 있었다는 메시지를 전달할 뿐이다.&lt;/li&gt;
&lt;li&gt;인터럽트는 바로 실행 중인 스레드에 실제적인 제한을 가해 멈추도록 하지 않는다, 단지 해당하는 스레드가 상황을 봐서 스스로 멈춰주기를 요청하는 것 뿐이다.&lt;/li&gt;
&lt;li&gt;작업 취소 기능을 구현하고자 할 때는 인터럽트가 가장 적절한 방법이라고 볼 수 있다.&lt;/li&gt;
&lt;li&gt;각 스레드는 각자의 인터럽트 정책을 갖고 있다. 따라서 해당 스레드에서 인터럽트 요청을 받았을 때 어떻게 동작할지를 정확하게 알고 있지 않은 경우에는 함수로 인터럽트를 걸어서는 안된다.&lt;/li&gt;
&lt;li&gt;InterruptedException이 발생했을 때 처리할 수 있는 실질적인 방법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;발생한 예외를 호출 스택의 사우이 메소드로 전달한다. 이 방법을 사용하는 메소드 역시 인터럽트를 걸수 있는 블로킹 메서드가 된다.&lt;/li&gt;
&lt;li&gt;호출 스택의 상단에 위치한 메소드가 직접 처리할 수 있도록 인터럽트 상태를 유지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;catch 블록에서 InterruptedException을 잡아낸 다음 그대로 먹어버리는 일은 하지 말아야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 스레드의 인터럽트 정책을 개별 작업에서 정확하게 구현하고 있다면 아무 일도 하지 않아도 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;스레드의 인터럽트 처리 정책을 정확하게 구현하는 작업만이 인터럽트 요청을 삼켜버릴 수 있다. 일반적인 용도로 작성된 작업이나 라이브러리 메소드는 인터럽트 요청을 그냥 삼켜버려서는 안된다.&lt;/li&gt;
&lt;li&gt;Future.get 메소드에서 InterruptedException이 발생하거나 TimeoutException이 발생했을 때, 만약 예외 상황이 발생한 작업의 결과는 필요가 없다고 한다면 해당 작업에 대해 Future.cancel 메소드를 호출해 작업을 중단시켜야한다.&lt;/li&gt;
&lt;li&gt;ThreadPoolExecutor클래스의 newTaskFor 메소드를 오버라이드하여 인터럽트 처리를 하게 된다면 작업을 중단하는 과정에서도 응답 속도를 떨어뜨리지 않으면서 인터럽트에 대응하는 블로킹 메소드를 안전하게 호출할 수 있을 뿐만 아니라 대기상태에 들어갈 수 있는 소켓I/O 메소드와 같은 기능도 호출 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스레드&amp;nbsp;기반&amp;nbsp;서비스&amp;nbsp;중단&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스레드&amp;nbsp;기반&amp;nbsp;서비스를&amp;nbsp;생성한&amp;nbsp;메소드보다&amp;nbsp;생성된&amp;nbsp;스레드&amp;nbsp;기반&amp;nbsp;서비스가&amp;nbsp;오래&amp;nbsp;실행될&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;상황이라면&amp;nbsp;스레드&amp;nbsp;기반&amp;nbsp;서비스에서는&amp;nbsp;항상&amp;nbsp;종료시키는&amp;nbsp;방법을&amp;nbsp;제공해야&amp;nbsp;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;비정상적인&amp;nbsp;스레드&amp;nbsp;종료&amp;nbsp;상황&amp;nbsp;처리&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;잠깐&amp;nbsp;실행하고&amp;nbsp;마는&amp;nbsp;애플리케이션이&amp;nbsp;아닌&amp;nbsp;이상&amp;nbsp;예외가&amp;nbsp;발생했을&amp;nbsp;때&amp;nbsp;로그&amp;nbsp;파일에&amp;nbsp;오류를&amp;nbsp;출력하는&amp;nbsp;간단한&amp;nbsp;기능만이라도&amp;nbsp;확보할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;모든&amp;nbsp;스레드를&amp;nbsp;대상으로&amp;nbsp;UncaughtExceptionHandler를&amp;nbsp;활용해야&amp;nbsp;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;JVM 종료&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데몬 스레드는 예고 없이 종료될 수 있기 때문에 애플리케이션 내부에서 시작시키고 종료시키며 사용하기에는 그다지 좋은 방법이 아니다.&lt;/li&gt;
&lt;li&gt;finalize 메소드는 사용하지 말자&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스레드 풀 활용&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;작업과&amp;nbsp;실행&amp;nbsp;정책&amp;nbsp;간의&amp;nbsp;보이지&amp;nbsp;않는&amp;nbsp;연결&amp;nbsp;관계&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 작업을 실행하고자 할 때 그에 맞는 실행 정책을 요구하는 경우도 있고, 특정 실행 정책 아래에서는 실행되지 않는 경우도 있다. 다른 작업에 의존성이 있는 작업을 실행해야 할 때는 스레드 풀의 크기를 충분히 크게 잡아서 작업이 큐에서 대기하거나 등록되지 못하는 상황이 없도록 해야 한다. 스레드 한정 기법을 사용하는 작업은 반드시 순차적으로 실행돼야 한다. 작업을 구현할 때는 나중에 유지보수를 진행할 때 해당 작업과 호환되지 않는 실행 정책 아래에서 실행하도록 변경해 애프리케이션의 안전성을 해치거나 실행되지 않는 경우를 막을 수 있도록 실행 정책과 관련된 내용을 문서로 남겨야 한다.&lt;/li&gt;
&lt;li&gt;완전히 독립적이지 않은 작업을 Executor에 등록할 때는 항상 스레드 부족 데드락이 발생할 수 있다는 사실을 염두에 둬야 하며, 작업을 구현한 코드나 Executor를 설정하는 설정 파일 등에 항상 스레드 풀의 크기나 설정에 대한 내용을 설명해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ThreadPoolExecutor&amp;nbsp;설정&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;크기가&amp;nbsp;고정된&amp;nbsp;풀보다는&amp;nbsp;newCachedThreadPool&amp;nbsp;팩토리&amp;nbsp;메소드가&amp;nbsp;생성해주는&amp;nbsp;Executor가&amp;nbsp;나은&amp;nbsp;선택일&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;크기가&amp;nbsp;고정된&amp;nbsp;스레드&amp;nbsp;풀은&amp;nbsp;자원&amp;nbsp;관리&amp;nbsp;측면에서&amp;nbsp;동시에&amp;nbsp;실행되는&amp;nbsp;스레드의&amp;nbsp;수를&amp;nbsp;제한해야&amp;nbsp;하는&amp;nbsp;경우에&amp;nbsp;현명한&amp;nbsp;선택이&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;네트웍으로&amp;nbsp;클라이언트의&amp;nbsp;요청을&amp;nbsp;받아&amp;nbsp;처리하는&amp;nbsp;애플리케이션과&amp;nbsp;같은&amp;nbsp;경우,&amp;nbsp;크기가&amp;nbsp;고정되어&amp;nbsp;있지&amp;nbsp;않다면&amp;nbsp;요청이&amp;nbsp;많아져&amp;nbsp;부하가&amp;nbsp;걸릴&amp;nbsp;때&amp;nbsp;문제가&amp;nbsp;커진다&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;ThreadPoolExecutor&amp;nbsp;상속&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ThreadPoolExecutor는&amp;nbsp;beforeExecute,&amp;nbsp;afterExecute,&amp;nbsp;terminated와&amp;nbsp;같은&amp;nbsp;훅을&amp;nbsp;상속하여&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;재귀&amp;nbsp;함수&amp;nbsp;병렬화&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정&amp;nbsp;작업을&amp;nbsp;여러&amp;nbsp;번&amp;nbsp;실행하는&amp;nbsp;반목문이&amp;nbsp;있을&amp;nbsp;때,&amp;nbsp;반복되는&amp;nbsp;각&amp;nbsp;작업이&amp;nbsp;서로&amp;nbsp;독립적이라면&amp;nbsp;병렬화해서&amp;nbsp;성능의&amp;nbsp;이점을&amp;nbsp;얻을&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;특히&amp;nbsp;반복문&amp;nbsp;내부의&amp;nbsp;작업을&amp;nbsp;개별적인&amp;nbsp;작업으로&amp;nbsp;구분해&amp;nbsp;실행하느라&amp;nbsp;추가되는&amp;nbsp;약간의&amp;nbsp;부하가&amp;nbsp;부담되지&amp;nbsp;않을&amp;nbsp;만큼&amp;nbsp;적지&amp;nbsp;않은&amp;nbsp;시간이&amp;nbsp;걸리는&amp;nbsp;작업이라야&amp;nbsp;더&amp;nbsp;효과를&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;GUI&amp;nbsp;애플리케이션&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;GUI는&amp;nbsp;왜&amp;nbsp;단일&amp;nbsp;스레드로&amp;nbsp;동작하는가&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스윙의&amp;nbsp;단일&amp;nbsp;스레드&amp;nbsp;규칙&amp;nbsp;-&amp;nbsp;스윙&amp;nbsp;컴포넌트와&amp;nbsp;모델&amp;nbsp;객체는&amp;nbsp;이벤트&amp;nbsp;스레드&amp;nbsp;내부에서만&amp;nbsp;생성하고,&amp;nbsp;변경하고,&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;장시간&amp;nbsp;실행되는&amp;nbsp;GUI&amp;nbsp;작업&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이벤트 스레드가 아닌 별도의 백그라운드 작업 스레드에서 작업을 진행하도록 한다.&lt;/li&gt;
&lt;li&gt;백그라운드 작업 스레드에서 작업이 완료되면 다시 이벤트 스레드 큐에 작업을 추가한다.&lt;/li&gt;
&lt;li&gt;Future 혹은 Future 태스크를 통해서 작업이 완료된 사항을 쉽게 처리할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;데이터&amp;nbsp;공유&amp;nbsp;모델&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터&amp;nbsp;모델을&amp;nbsp;여러&amp;nbsp;개의&amp;nbsp;스레드에서&amp;nbsp;공유해야&amp;nbsp;하는&amp;nbsp;경우라면&amp;nbsp;분할&amp;nbsp;데이터&amp;nbsp;모델을&amp;nbsp;사용하는&amp;nbsp;방법을&amp;nbsp;고려해보자,&amp;nbsp;스레드&amp;nbsp;안전하게&amp;nbsp;공유할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;데이터&amp;nbsp;모델을&amp;nbsp;만들어&amp;nbsp;사용하고자할&amp;nbsp;때&amp;nbsp;대기&amp;nbsp;상태에&amp;nbsp;들어가는&amp;nbsp;블로킹&amp;nbsp;문제,&amp;nbsp;일관성&amp;nbsp;문제,&amp;nbsp;구현하기에&amp;nbsp;복잡하다는&amp;nbsp;이유&amp;nbsp;등이&amp;nbsp;있다면&amp;nbsp;스레드&amp;nbsp;안전한&amp;nbsp;모델&amp;nbsp;대신&amp;nbsp;분할&amp;nbsp;데이터&amp;nbsp;모델을&amp;nbsp;추천한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3부&amp;nbsp;활동성,&amp;nbsp;성능,&amp;nbsp;테스트&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;활동성을&amp;nbsp;최대로&amp;nbsp;높이기&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;데드락&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 내부의 모든 스레드에서 필요한 락을 모두 같은 순서로만 사용한다면, 락 순서에 의한 데드락은 발생하지 않는다.&lt;/li&gt;
&lt;li&gt;락을 확보한 상태에서 에일리언 메소드를 호출한다면 가용성에 문제가 생길 수 있다. 에일리언 메소드 내부에서 다른 락을 확보하려고 하거나, 아니면 예상하지 못한 만큼 오랜 시간 동안 계속해서 실행된다면 호출하기 전에 확보했던 락이 필요한 다른 스레드가 계속해서 대기해야 하는 경우도 생길 수 있다.&lt;/li&gt;
&lt;li&gt;오픈 호출(락을 전혀 확보하지 않은 상태에서 메소드를 호출하는 것)만을 사용해야 한다거나 락을 확보하는 순서를 주의 깊게 정해야 한다는 사실은, 여러 객체가 조합된 코드의 동기화를 맞추는 것보다 동기화가 맞춰진 객체를 조합해 사용하는 것이 훨씬 복잡하다는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;프로그램을 작성할 때 최대한 오픈 호출 방법을 사용하도록 한다. 내부의 모든 부분에서 오픈 호출을 사용하는 프로그램은 락을 확보한 상태로 메소드를 호출하곤 하는 프로그램보다 데드락 문제를 찾아내기 위한 분석 작업을 훨씬 간편하게 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;데드락&amp;nbsp;방지&amp;nbsp;및&amp;nbsp;원인&amp;nbsp;추적&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두&amp;nbsp;개의&amp;nbsp;락을&amp;nbsp;한꺼번에&amp;nbsp;확보해야&amp;nbsp;하는&amp;nbsp;경우에&amp;nbsp;타임아웃을&amp;nbsp;지정하는&amp;nbsp;방법을&amp;nbsp;적용하면,&amp;nbsp;프로그램&amp;nbsp;전체에서&amp;nbsp;모두&amp;nbsp;타임아웃을&amp;nbsp;사용하지&amp;nbsp;않는다&amp;nbsp;해도&amp;nbsp;데드락을&amp;nbsp;방지하는&amp;nbsp;데&amp;nbsp;효과를&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;그&amp;nbsp;밖의&amp;nbsp;활동성&amp;nbsp;문제점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스레드 우선 순위를 변경하고 싶다 해도 꾹 참자, 우선 순위를 변경하고 나면 플랫폼에 종속적인 부분이 많아지며, 따라서 활동성 문제를 일으키기 쉽다, 대부분의 병렬 애플리케이션은 모든 스레드의 우선 순위에 기본값을 사용하고 있다.&lt;/li&gt;
&lt;li&gt;서로 락을 획득한 상태에서 상대방의 락을 기다리다가 타임아웃이 발생했을 때 재시도를 계속해서 시도하지만 결국 자원을 얻지 못하는 상태를 라이브락이라고 한다, 이럴 경우 재시도할 때 잠시 기다리는 시간을 임의로 지정하게 되면 라이브락을 방지할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;성능, 확장성&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;성능에&amp;nbsp;대해&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확장성은 CPU, 메모리, 디스크, I/O 처리 장치 등의 추가적인 장비를 사용해 처리량이나 용량을 얼마나 쉽게 키울 수 있는지를 말한다.&lt;/li&gt;
&lt;li&gt;최적화 기법을 너무 이른 시점에 적용하지 말아야 한다, 일단 제대로 동작하게 만들고 난 다음에 빠르게 동작하도록 최적화해야 하며, 예상한 것보다 심각하게 성능이 떨어지는 경우에만 최적화 기법을 적용하는 것으로도 충분하다.&lt;/li&gt;
&lt;li&gt;특정 방법이 다른 방법보다 빠르다고 말하기전에 다음과 같은 질문에 대답해 볼 필요가 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;빠르다 단어가 무엇을 의미하는가&lt;/li&gt;
&lt;li&gt;어떤 조건을 갖춰야 이 방법이 실제로 빠르게 동작할 것인가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부하가 적을 때?, 부하가 걸릴 때?, 데이터가 많을 때?. 데이터가 적을 때?&lt;/li&gt;
&lt;li&gt;이런 질문에 대한 대답에 명확한 수치를 보여줄 수 있는가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;위 조건에 해당하는 경우가 얼마나 많이 발생하는가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이런 질문에 대한 대답에 명확한 수치를 보여줄 수 있는가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;조건이 달라지는 다른 상황에서도 같은 코드를 사용할 수 있는가&lt;/li&gt;
&lt;li&gt;이 방법으로 성능을 개선하고자 할 때 숨겨진 비용, 즉 개발 비용이나 유지보수 비용이 증가하는 부분이 어느정도인지, 그런 비용을 감수함녀서까지 성능 개선 작업을 해야하는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추측하지 말고 실제로 측정해보자&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;암달의&amp;nbsp;법칙&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든&amp;nbsp;병렬&amp;nbsp;프로그램에는&amp;nbsp;항상&amp;nbsp;순차적으로&amp;nbsp;실행돼야만&amp;nbsp;하는&amp;nbsp;부분이&amp;nbsp;존재한다.&amp;nbsp;만약&amp;nbsp;그런&amp;nbsp;부분이&amp;nbsp;없다고&amp;nbsp;생각한다면,&amp;nbsp;프로그램&amp;nbsp;코드를&amp;nbsp;다시&amp;nbsp;한&amp;nbsp;번&amp;nbsp;들여다보자.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스레드와 비용&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;경쟁&amp;nbsp;조건에&amp;nbsp;들어가지&amp;nbsp;않는&amp;nbsp;동기화&amp;nbsp;블록에&amp;nbsp;대해서는&amp;nbsp;그다지&amp;nbsp;걱정하지&amp;nbsp;않아도&amp;nbsp;좋다.&amp;nbsp;동기화&amp;nbsp;블록의&amp;nbsp;기본적인&amp;nbsp;구조가&amp;nbsp;상당히&amp;nbsp;빠르게&amp;nbsp;동작할&amp;nbsp;뿐만&amp;nbsp;아니라&amp;nbsp;JVM&amp;nbsp;수준에서&amp;nbsp;동기화와&amp;nbsp;관련한&amp;nbsp;추가적인&amp;nbsp;최적화&amp;nbsp;작업을&amp;nbsp;진행하기&amp;nbsp;때문에&amp;nbsp;동기화&amp;nbsp;관련&amp;nbsp;부하를&amp;nbsp;줄이거나&amp;nbsp;아예&amp;nbsp;없애주기도&amp;nbsp;한다.&amp;nbsp;대신&amp;nbsp;경쟁&amp;nbsp;조건이&amp;nbsp;발생하는&amp;nbsp;동기화&amp;nbsp;블록을&amp;nbsp;어떻게&amp;nbsp;최적화할지에&amp;nbsp;대해서&amp;nbsp;고민하자&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;락 경쟁 줄이기&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;병렬 애플리케이션에서 확장성에 가장 큰 위협이 되는 존재는 바로 특정 자원을 독점적으로 사용하도록 제한하는 락이다.&lt;/li&gt;
&lt;li&gt;락 경쟁 조건을 줄일 수 있는 몇가지 방법이 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;락을 확보한 채로 유지되는 시간을 최대한 줄여라&lt;/li&gt;
&lt;li&gt;락을 확보하고자 요청하는 횟수를 최대한 줄여라&lt;/li&gt;
&lt;li&gt;독점적인 락 대신 병렬성을 크게 높여주는 여려 가지 조율 방법을 사용하라&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;락을 하나에서 둘로 분할하는 방법은 경쟁 조건이 아주 심하지는 않지만 그래도 어느 정도 경쟁이 발생하고 있는 경우에 가장 큰 효과를 볼 수 있다. 만약 경쟁 조건이 심한 락을 두개로 분할하고 나면 결국 경쟁이 심한 락이 두개가 생기는 모양새가 될 수 있다.&lt;/li&gt;
&lt;li&gt;스레드 동기화하는 것 보다 메모리에 객체를 할당하는 일이 훨씬 부담이 적다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;컨텍스트 스위치 부하 줄이기&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;요청을 처리하는 스레드의 외부로 I/O 작업을 뽑아내는 방법은 요청을 처리하는 평균 시간을 줄여주는 좋은 방법이다. 예를 들어 log 메소드를 호출하는 스레드는 더 이상 출력 스트림에 대한 락을 확보할 필요도 없고 I/O 작업이 완료될 때까지 대기하지 않아도 된다.&lt;/li&gt;
&lt;li&gt;로그를 출력하고자 요청하는 다수의 스레드에서 발생할 I/O 연산을 단 하나의 스레드에서 처리하도록 한군데로 몰아두기 때문에 로그 출력 스트림을 공유하지 않아도 되고 따라서 대기 상태에 들어갈 수 있는 원인을 미연에 방지하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1742890274336&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

class AsyncLogger {
    private static final BlockingQueue&amp;lt;String&amp;gt; logQueue = new LinkedBlockingQueue&amp;lt;&amp;gt;();
    private static final Thread logThread;

    static {
        logThread = new Thread(() -&amp;gt; {
            while (true) {
                try {
                    String logMessage = logQueue.take();  //   큐에서 로그 메시지 가져오기
                    System.out.println(logMessage);  //   단일 스레드에서만 로그 출력
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });

        logThread.setDaemon(true); // 프로그램 종료 시 자동 종료
        logThread.start();
    }

    public static void log(String message) {
        logQueue.offer(message);  //   로그 메시지를 큐에 추가 (즉시 반환, 블로킹 없음)
    }
}

class RequestHandler implements Runnable {
    private final int requestId;

    public RequestHandler(int requestId) {
        this.requestId = requestId;
    }

    @Override
    public void run() {
        long startTime = System.currentTimeMillis();
        AsyncLogger.log(&quot;Request &quot; + requestId + &quot; started.&quot;);  //   로그는 별도 스레드로 넘김

        //   I/O 작업을 직접 수행하는 대신 비동기적으로 실행
        new Thread(() -&amp;gt; {
            try {
                Thread.sleep(100); //   가상의 I/O 작업 (100ms)
                AsyncLogger.log(&quot;Request &quot; + requestId + &quot; completed.&quot;);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();

        long elapsedTime = System.currentTimeMillis() - startTime;
        System.out.println(&quot;Request &quot; + requestId + &quot; handled in &quot; + elapsedTime + &quot;ms.&quot;);
    }
}

public class Main {
    public static void main(String[] args) {
        for (int i = 1; i &amp;lt;= 5; i++) {
            new Thread(new RequestHandler(i)).start();  //   요청 스레드 여러 개 실행
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;병렬&amp;nbsp;프로그램&amp;nbsp;테스트&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정확성 테스트&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Thread.getState 메소드를 병렬성을 제어하는 용도로 사용하지 말아야 한다. JVM의 구현 방법에 따라 스핀 대기 기법을 활용할 수도 있으므로 특정 스레드가 대기 상태에 들어갔다고 해서 항상 스레드가 WAITING 또는 TIMED_WAITING 상태에 놓여있다고 볼 수 없기 때문이다.&lt;/li&gt;
&lt;li&gt;안전성을 테스트하는 프로그램을 효과적으로 작성하려면 뭔가 문제가 발생해을 때 잘못 사용되는 속성을 높은 확률로 찾아내는 작업을 해야 함과 동시에 오류를 확인하는 코드가 테스트 대상의 병렬성을 인위적으로 제한해서는 안 된다는 점을 고려해야 한다. 테스트하는 대상 속성의 값을 확인할 때 추가적인 동기화 작업을 하지 않아도 된다면 가장 좋은 상태라고 볼 수 있다.&lt;/li&gt;
&lt;li&gt;테스트 프로그램은 스레드가 교차 실행되는 경우의 수를 최대한 많이 확보할 수 있도록 CPU 가 여러 개 장착된 시스템에서 돌려보는 게 좋다. 그렇다고 CPU가 수십 개 달렸다고 해서 서너 개의 CPU가 장착된 시스템에 비해 테스트 효율이 좋아진다고 보기는 어렵다. 절묘한 타이밍에 공유된 데이터를 사용하다 나타나는 오류를 찾으려면 CPU가 많이 있는 것보다 스레드를 더 많이 돌리는 편이 낫다. 스레드가 많아지면 실행 중인 스레드와 대기 상태에 들어간 스레드가 서로 교차하면서 스레드 간의 상호 작용이 발생하는 경우의 수가 많아지기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;성능 측정의 함정 피하기&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;훌륭한&amp;nbsp;성능&amp;nbsp;측정&amp;nbsp;프로그램을&amp;nbsp;작성하려면&amp;nbsp;최적화&amp;nbsp;컴파일러가&amp;nbsp;의미&amp;nbsp;없는&amp;nbsp;코드를&amp;nbsp;제거하는&amp;nbsp;과정에&amp;nbsp;성능&amp;nbsp;측정상&amp;nbsp;필요한&amp;nbsp;부분까지&amp;nbsp;제거하지&amp;nbsp;않도록&amp;nbsp;약간의&amp;nbsp;편법을&amp;nbsp;써야&amp;nbsp;할&amp;nbsp;필요가&amp;nbsp;있다.&amp;nbsp;그러려면&amp;nbsp;프로그램&amp;nbsp;코드가&amp;nbsp;만들어내는&amp;nbsp;모든&amp;nbsp;결과&amp;nbsp;값을&amp;nbsp;프로그램&amp;nbsp;어디에선가&amp;nbsp;사용하도록&amp;nbsp;해야&amp;nbsp;한다.&amp;nbsp;물론&amp;nbsp;그&amp;nbsp;때문에&amp;nbsp;추가적으로&amp;nbsp;동기화를&amp;nbsp;해야&amp;nbsp;하거나&amp;nbsp;더&amp;nbsp;많은&amp;nbsp;자원을&amp;nbsp;소모하도록&amp;nbsp;하지는&amp;nbsp;않는&amp;nbsp;것이&amp;nbsp;좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4부 고급 주제&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;명시적인 락&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Lock과 ReentrantLock&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;락을 확보하고자 대기하고 있는 상태의 스레드에는 인터럽트 거는일이 불가능하고 대기 상태에 들어가지 않으면서 락을 화보하는 방법등이 꼭 필요한 상황이 있기 때문에 명시적인 락 클래스를 따로 만들게 된 것이다.&lt;/li&gt;
&lt;li&gt;ReentrantLock을 사용하면 해당하는 블록의 실행이 끝나고 통제권이 해당 블록을 떠나는 순간 락을 자동으로 해제하지 않기 때문에 굉장히 위험한 코드가 될 가능성이 높다, 락을 블록이 끝나는 시점에 finally 블록을 사용해 해제해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;성능에&amp;nbsp;대한&amp;nbsp;고려&amp;nbsp;사항&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;성능&amp;nbsp;측정&amp;nbsp;결과는&amp;nbsp;우미깅는&amp;nbsp;대상이다.&amp;nbsp;바로&amp;nbsp;어제&amp;nbsp;X가&amp;nbsp;Y보다&amp;nbsp;빠르다는&amp;nbsp;결과를&amp;nbsp;산출했던&amp;nbsp;성능&amp;nbsp;테스트를&amp;nbsp;오늘&amp;nbsp;실행해보면&amp;nbsp;다른&amp;nbsp;결과를&amp;nbsp;얻을&amp;nbsp;수도&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;공정성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대부분&amp;nbsp;공정하게&amp;nbsp;순서를&amp;nbsp;관리해서&amp;nbsp;얻는&amp;nbsp;장점보다&amp;nbsp;불공정하게&amp;nbsp;처리해서&amp;nbsp;얻는&amp;nbsp;성능상의&amp;nbsp;이점이&amp;nbsp;크다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;synchronized&amp;nbsp;또는&amp;nbsp;ReentrantLock&amp;nbsp;선택&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ReentrantLock은 암묵적인 락만으로는 해결할 수 없는 복잡한 상황에서 사용하기 위한 고급 동기화 기능이다. 다음과 같은 고급 동기화 기법을 사용해야하는 경우에만 ReentrantLock을 사용하도록 하자
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;락을 확보할 때 타임아웃을 지정해야 하는 경우&lt;/li&gt;
&lt;li&gt;폴링의 형태로 락을 확보하고자 하는 경우&lt;/li&gt;
&lt;li&gt;락을 확보하느라 대기 상태에 들어가 있을 때 인터럽트를 걸 수 있어야 하는 경우&lt;/li&gt;
&lt;li&gt;대기 상태 큐 처리 방법을 공정하게 해야 하는 경우&lt;/li&gt;
&lt;li&gt;코드가 단일 블록의 형태를 넘어서는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;읽기-쓰기&amp;nbsp;락&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;읽기&amp;nbsp;작업은&amp;nbsp;여러&amp;nbsp;개를&amp;nbsp;한꺼번에&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있지만&amp;nbsp;쓰기&amp;nbsp;작업은&amp;nbsp;혼자만&amp;nbsp;동작할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;구조의&amp;nbsp;동기화를&amp;nbsp;처리해주는&amp;nbsp;락&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;동기화&amp;nbsp;클래스&amp;nbsp;구현&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;조건&amp;nbsp;큐&amp;nbsp;활용&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조건 큐를 올바로 사용하기 위한 가장 핵심적인 요소는 바로 해당 객체가 대기하게 될 조건 서술어를 명확하게 구분해내는 일이다.&lt;/li&gt;
&lt;li&gt;조건 큐와 연결된 조건 서술어를 항상 문서로 남겨야 하며, 그 조건 서술어에 영향을 받는 메소드가 어느 것인지도 명시해야 한다.&lt;/li&gt;
&lt;li&gt;wait 메소드를 호출하는 모든 경우에는 항상 조건 서술어가 연결돼 있다. 특정 조건 서술어를 놓고 wait 메소드를 호출할 때 호출자는 항상 해당하는 조건 큐에 대한 락을 이미 확보한 상태여야 한다. 또한 확보한 락은 조건 서술어를 확인하는 데 필요한 모든 상태 변수를 동기화하고 있어야 한다.&lt;/li&gt;
&lt;li&gt;조건부 wait 메서드를 사용할 때에는
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;항상 조건 서술어(작업을 계속 진행하기 전에 반드시 확인해야 하는 확인 절차)를 명시해야 한다.&lt;/li&gt;
&lt;li&gt;wait 메소드를 호출하기 전에 조건 서술어를 확인하고 wait에서 리턴된 이후에도 조건 서술어를 확인해야 한다.&lt;/li&gt;
&lt;li&gt;wait 메소드는 항상 반복문 내부에서 호출해야 한다.&lt;/li&gt;
&lt;li&gt;조건 서술어를 확인하는 데 관련된 모든 상태 변수는 해당 조건 큐의 락에 의해 동기화돼 있어야 한다.&lt;/li&gt;
&lt;li&gt;wait, notify, notifyAll 메소드를 호출할 때는 조건 큐에 해당하는 락을 확보하고 있어야 한다.&lt;/li&gt;
&lt;li&gt;조건 서술어를 확인한 이후 실제로 작업을 실행해 작업이 끝날 때까지 락을 해제해서는 안 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;특정 조건을 놓고 wait 메소드를 호출해 대기 상태에 들어간다면 해당 조건을 만족하게 된 이후에 반드시 알림 메소드를 사용해 대기 상태에서 빠져나오도록 해야 한다.&lt;/li&gt;
&lt;li&gt;notifyAll 대신 notify 메소드를 사용하려면 다음과 같은 조건에 해당하는 경우에만 사용하는 것이 좋다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단일 조건에 따른 대기 상태에서 깨우는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당하는 조건 큐에 단 하나의 조건만 사용하고 있는 경우이고, 따라서 각 스레드는 wait 메소드에서 리턴될 때 동일한 방법으로 실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;한 번에 하나씩 처리하는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조건 변수에 대한 알림 메소드를 호출하면 하나의 스레드만 실행시킬 수 있는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;명시적인&amp;nbsp;조건&amp;nbsp;객체&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;암묵적인 조건 큐를 일반화한 형태는 Condition 클래스이다&lt;/li&gt;
&lt;li&gt;암묵적인 락에서 사용하던 wait, notify, notifyAll 메소드의 기능은 Condition 클래서에서는 각각 await, signal, signalAll 메소드이다. 자바에서 모든 클래스가 그렇지만 Condition 클래스 역시 Object를 상속받기 때문에 Condition 객체에도 wait, notify, notifyAll 메소드가 포함돼 있다. 따라서 실수로 await 대신 wait 메소드를 사용하거나 notify 대신 signal 메소드를 사용하면 동기화 기능에 큰 문제가 생길 수 있다.&lt;/li&gt;
&lt;li&gt;Condition객체 사용 유무는 ReentrantLock과 synchronized의 선택 문제와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동기화&amp;nbsp;클래스의&amp;nbsp;내부&amp;nbsp;구조&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AbstractQueuedSynchronizer는 락이나 기타 동기화 클래스를 만들수 있는 프레임웍 역할을 한다.&lt;/li&gt;
&lt;li&gt;AQS 기반으로 만들어진 동기화 클래스는 대기 상태에 들어갈 수 있는 지점이 단 한군데이기 때문에 컨텍스트 스위칭 부하를 줄일 수 있고 결과적으로 전체적인 성능을 높일 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단일&amp;nbsp;연산&amp;nbsp;변수와&amp;nbsp;넌블로킹&amp;nbsp;동기화&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;락의&amp;nbsp;단점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;경쟁이 심한 상황이 되면 컨텍스트 스위칭 부하와 함께 스케줄링 관련 지연 현상이 발생하면서 성능이 떨어진다, 락을 아주 짧은 시간만 사용할 경우 그 작업을 위해서 스레드를 대기 상태에 들어가게 하는 일이 굉장한 단점이 될 수 있다.&lt;/li&gt;
&lt;li&gt;또 다른 단점은 스레드가 락을 확보하기 위해 대기하고 있는 상태에서 대기 중인 스레드는 다른 작업을 전혀 못한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;병렬&amp;nbsp;연산을&amp;nbsp;위한&amp;nbsp;하드웨어적인&amp;nbsp;지원&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CAS(compare and swap)은 대상 메모리 위치에 들어 있는 값이 예상하는 기존값이라고 생각되며, 만약 실제로 대상 메모리 위치의 값이 예상하는 기존값이라면 새로 설정한 값으로 바꿔 넣어라, 만약 대상 메모리 위치의 값이 예상하는 기존값이 아니라면 아무 작업도 하지 말고 대상 메모리 위치의 값이 뭔지 알려다라는 연산으로 낙관적인 기법이다.&lt;/li&gt;
&lt;li&gt;만약 여러 스레드가 동시에 CAS 연산을 사용해 한 변수의 값을 변경하려고 한다면, 스레드 가운데 하나만 성공적으로 값을 변경하고 나머지 스레드는 모두 실패한다.&lt;/li&gt;
&lt;li&gt;CAS 연산을 사용하면 다른 스레드와 간섭이 발생했는지를 확인할 수 있기 때문에 락을 사용하지 않으면서도 읽고-변경하고-쓰는 연산을 단일 연산으로 구현해야한다는 문제를 간단하게 해결해준다.&lt;/li&gt;
&lt;li&gt;CAS 연산을 프로그램에서 직접 사용하면 JVM에서 특별한 루틴을 실행해야 할 필요도 없고 운영체제의 함수를 호출해야 할 필요도 없고 스케줄링 관련 작업을 따로 조절해야 할 필요도 없다, 애플리케이션 수준에서는 코드가 더 복잡해 보이지만 JVM이나 운영체제의 입장에서는 훨씬 적은 양의 프로그램만 실행하는 셈이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단일&amp;nbsp;연산&amp;nbsp;변수&amp;nbsp;클래스&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확장성을 가장 높일 수 있는 방법은 스레드 간의 경쟁이 발생하지 않도록 미연에 방지하는 방법이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EX) ThreadLocal&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;넌블로킹&amp;nbsp;알고리즘&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;넌블로킹 알고리즘은 데드락이나 우선 순위 역전등의 문제점이 발생하지 않지만 지속적으로 재시도만 하고 있을 가능성이 이씩 때문에 라이브락의 문제점이 발생할 가능성이 있다.&lt;/li&gt;
&lt;li&gt;넌블로킹 알고리즘을 작성할 때 핵심은 단일 연산의 범위를 단 하나의 변수로 제한하는 부분이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;자바&amp;nbsp;메모리&amp;nbsp;모델&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;자바&amp;nbsp;메모리&amp;nbsp;모델은&amp;nbsp;무엇이며,&amp;nbsp;왜&amp;nbsp;사용해야&amp;nbsp;하는가?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;미리 발생 현상에 대한 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램 순서 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 스레드를 놓고 봤을 때 프로그램된 순서에서 앞서있는 작업은 동일 스레드에서 뒤에 실행되도록 프로그램된 작업보다 미리 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모니터 잠금 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 모니터 잠금 작업이 뒤이어 오는 모든 모니터 잠금 작업보다 미리 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;volatile 변수 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;volatile 변수에 대한 쓰기 작업은 이후에 따라오는 해당 변수에 대한 모든 읽기 작업보다 미리 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;스레드 시작 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 스레드에 대한 Thread.start 작업은 시작된 스레드가 갖고 있는 모든 작업보다 미리 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;스레드 완료 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스레드 내부의 모든 작업은 다른 스레드에서 해당 스레드가 완료됐다는 점을 파악하는 시점보다 미리 발생한다. 특정 스레드가 완료됐는지를 판단하는 것은 Thread.join 메소드가 리턴되거나 Thread.isAlive 메소드가 false를 리턴하는지 확인하는 방법을 말한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;인터럽트 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 스레드를 대상으로 interrupt 메소드를 호출하는 작업은 인터럽트 당한 스레드에서 인터럽트를 당했다는 사실을 파악하는 일보다 미리 발생한다. 인터럽트를 당했다는 사실을 파악하려면 InterruptedException을 받거나 isInterrupted 메소드 또는 interrupted 메소드를 호출하는 방법을 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;완료 메소드 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 객체에 대한 생성 메소드가 완료되는 시점은 완료 메소드가 시작하는 시점보다 미리 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;전이성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A가 B보다 미리 발생하고, B가 C보다 미리 발생한다면, A는 C보다 미리 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;안전한&amp;nbsp;공개&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;불변&amp;nbsp;객체가&amp;nbsp;아닌&amp;nbsp;이상&amp;nbsp;특정&amp;nbsp;객체를&amp;nbsp;공개하는&amp;nbsp;일이&amp;nbsp;그&amp;nbsp;객체를&amp;nbsp;사용하려는&amp;nbsp;작업보다&amp;nbsp;미리&amp;nbsp;발생하도록&amp;nbsp;구성돼&amp;nbsp;있지&amp;nbsp;않다면&amp;nbsp;다른&amp;nbsp;스레드에서&amp;nbsp;생성한&amp;nbsp;객체를&amp;nbsp;사용하는&amp;nbsp;작업은&amp;nbsp;안전하지&amp;nbsp;않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;초기화&amp;nbsp;안전성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초기화 안전성이 확보돼 있다면 완전하게 구성된 객체를 대상으로 해당 객체가 어떻게 공개됐던 간에 생성 메소드가 지정하는 모든 final 변수의 값을 어떤 스레드건 간에 올바르게 읽어갈 수 있다는 점을 보장한다. 또한 완전하게 구성된 객체 내부에 final로 선언된 객체를 거쳐 사용할 수 있는 모든 변수(예를 들어 final로 선언된 배열의 항목 또는 final로 선언된 HashMap 내부에 들어 있는 값 등) 역시 다른 스레드에서 안전하게 볼 수 있다는 점도 보장된다.&lt;/li&gt;
&lt;li&gt;초기화 안전성은 생성 메소드가 완료되는 시점에 final로 선언된 변수와 해당 변수를 거쳐 접근할 수 있는 값에 대해서만 가시성을 보장한다. final로 선언되지 않은 변수나 생성 메소드가 종료된 이후에 변경되는 값에 대해서는 별도의 동기화 구문을 적용해야 가시성을 확보할 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Book</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/21</guid>
      <comments>https://immigrationssu.tistory.com/entry/%EC%9A%94%EC%95%BD-%EB%A9%80%ED%8B%B0-%EC%BD%94%EC%96%B4%EB%A5%BC-100-%ED%99%9C%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9E%90%EB%B0%94-%EB%B3%91%EB%A0%AC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D#entry21comment</comments>
      <pubDate>Tue, 25 Mar 2025 17:23:24 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot] AWS Opensearch를 사용하다 OOM을 만나다.</title>
      <link>https://immigrationssu.tistory.com/entry/Spring-Boot-AWS-Opensearch%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8B%A4-OOM%EC%9D%84-%EB%A7%8C%EB%82%98%EB%8B%A4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;이 글은 Java/Spring Boot 기반 서비스를 운영하며 Thread 누수 문제를 분석하고 해결한 과정을 기록한 글입니다.&lt;/i&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 문제 발생&lt;/h2&gt;
&lt;pre id=&quot;code_1736669264315&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Caused by: java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached
	at java.base/java.lang.Thread.start0(Native Method)
	at java.base/java.lang.Thread.start(Thread.java:1526)
	at java.base/java.util.Timer.&amp;lt;init&amp;gt;(Timer.java:188)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;java.lang.OutOfMemoryError:&amp;nbsp;unable&amp;nbsp;to&amp;nbsp;create&amp;nbsp;native&amp;nbsp;thread&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 에러는 &lt;b&gt;Java에서 너무 많은 Thread를 생성하여 더 이상 Thread를 생성할 수 없을 때 발생&lt;/b&gt;하는 에러이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;갑자기 API 호출이 계속해서 실패하여 로그를 확인해보니 위 에러가 발생하고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상했다. 여태 이상없이 잘 돌고 있던 서비스에서 갑자기 OOM이 간헐적으로 터졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드 밸런싱  처리도 되어있고 트래픽도 높지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인이 무엇일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 원인 분석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Thread 생성 관련 OOM이 발생했다는 것은 Thread가 점진적으로 계속 생성만 되고 종료되지 않는다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확한 원인 분석을 위해 VisualVM을 통해 활성 Thread를 모니터링 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;43&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csNINy/btsLJ7fkhuQ/fbtOnnbRcELj6svKY0nn8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csNINy/btsLJ7fkhuQ/fbtOnnbRcELj6svKY0nn8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csNINy/btsLJ7fkhuQ/fbtOnnbRcELj6svKY0nn8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsNINy%2FbtsLJ7fkhuQ%2FfbtOnnbRcELj6svKY0nn8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1212&quot; height=&quot;43&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;43&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;i&gt;(문제가 발생했을 당시 Thread 덤프를 떠놓지 않아 정상적인 Thread 모니터링 이미지로 대체..)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;I/O dispatcher&lt;/b&gt; Thread가 특정 간격으로 점진적으로 쌓이고 있는 것을 발견했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 뭐 때문에 이렇게 Thread가 쌓이는지 다시 API 서버 로그를 확인해보니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS Opensearch에서 데이터를 조회하는 API를 호출할 때 마다 Thread가 쌓이고 있는 것을 확인했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 증가하는 Thread 분석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점진적으로 쌓이던 Thread(I/O dispatcher)도 확인했고 Thread를 쌓이게 만들었던 원인(AWS Opensearch)도 발견했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 이 둘은 무슨 관계가 있는걸까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 프로젝트는 &lt;a href=&quot;https://opensearch.org/docs/latest/clients/java/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Opensearch-client&lt;/a&gt;를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 OpenSearchClient를 생성한 후 사용해야한다.&lt;/p&gt;
&lt;pre id=&quot;code_1736672757880&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;publci OpenSearchClient openSearchClient() {
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(openSearchId, openSearchPassword));

        RestClient restClient = RestClient.builder(new HttpHost(openSearchHost, openSearchPort, &quot;https&quot;))
                .setHttpClientConfigCallback(
                        httpClientBuilder -&amp;gt; httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
                )
                .build();

        RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        return new OpenSearchClient(transport);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RestClinet를 생성할 때  HttpAsyncClientBuilder를 통해 CloseableHttpAsyncClient 추상 클래스를 구현 &lt;b&gt;InternalHttpAsyncClient&lt;/b&gt;를 생성하여 사용하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, Connection 관리 및 네트워크 I/O 처리를 위해 IOReactor를 사용하게 되면서 &lt;b&gt;I/O Dispatch Thread가 생성&lt;/b&gt;되게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1736674154760&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;httpClientBuilder -&amp;gt; httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
                                .setDefaultIOReactorConfig(IOReactorConfig.custom()
                                .setIoThreadCount(1)
                                .build())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 처럼 IOReactor에서 사용할 Thread의 개수도 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 설정하지 않을 시 서버 CPU의 코어 수를 기반으로 I/O Thread가 생성된다.&lt;/p&gt;
&lt;pre id=&quot;code_1736674439791&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//IOReactorConfig.class

public static int getDefaultMaxIoThreadCount() {
    return DefaultMaxIoThreadCount &amp;gt; 0 ? DefaultMaxIoThreadCount : Runtime.getRuntime().availableProcessors();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;점진적으로 쌓이던 Thread(I/O dispatcher)와 Thread를 쌓이게 만들었던 원인(AWS Opensearch)의 상관관계도 파악했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 왜 에러가 발생한걸까?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 허무했고 어이가 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenSearchClient를 Bean으로 관리하지 않고 조회시 마다 Client를 새로 생성하며 발생한 문제였다.(너무 어처구니 없었다..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심지어 IOReactor의 설정도 되어있지 않아 CPU 코어 수 만큼 Thread가 생성되고 있던 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 잘 사용되지 않던 API가 갑자기 사용량이 늘면서 뒤늦게서야 문제를 파악하게 된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenSearchClient를 사용할 땐 꼭 Bean으로 등록하거나 Client를 사용하고 나면 꼭 Close를 해주자..&lt;/p&gt;
&lt;pre id=&quot;code_1736675134803&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;opensearch._transport().close();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Project</category>
      <category>AWS</category>
      <category>java</category>
      <category>OpenSearch</category>
      <category>spring boot</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/20</guid>
      <comments>https://immigrationssu.tistory.com/entry/Spring-Boot-AWS-Opensearch%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8B%A4-OOM%EC%9D%84-%EB%A7%8C%EB%82%98%EB%8B%A4#entry20comment</comments>
      <pubDate>Sun, 12 Jan 2025 18:47:40 +0900</pubDate>
    </item>
    <item>
      <title>8. Instructions: Language of the Computer 4</title>
      <link>https://immigrationssu.tistory.com/entry/8-Instructions-Language-of-the-Computer-4</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KOCW 최규상 교수님 컴퓨터구조 강의 정리&lt;br /&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br /&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : 컴퓨터 구조 및 설계 - David A. Patterson,John L. Hennessy&lt;br /&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=f64448266743ced9&quot;&gt;http://www.kocw.net/home/cview.do?lid=f64448266743ced9&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. 32-bit Constants&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V0Lrh/btq2E9NGoiJ/pmcrD9y8j1x2KXqce9Ozq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V0Lrh/btq2E9NGoiJ/pmcrD9y8j1x2KXqce9Ozq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V0Lrh/btq2E9NGoiJ/pmcrD9y8j1x2KXqce9Ozq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV0Lrh%2Fbtq2E9NGoiJ%2FpmcrD9y8j1x2KXqce9Ozq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;536&quot; height=&quot;365&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;MIPS에서는 immediate는 16bit이다.&lt;br /&gt;32 bit을 처리하기 위해선 2개의 instructuion이 필요하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;lui rt, constant&lt;/b&gt;&lt;br /&gt;상수값이 target register의 상위 16bit로 복사된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ori $s0, $s0, 2304&lt;/b&gt;&lt;br /&gt;상수값이 target register의 하위 16bit로 복사된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2개의 instruction을 통해 32bit 상수를 만들 수 있게 되는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;2. Branch Addressing&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPKV1S/btq2DEN9XoB/udkvYJtO4RF9cvHuC1R17k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPKV1S/btq2DEN9XoB/udkvYJtO4RF9cvHuC1R17k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPKV1S/btq2DEN9XoB/udkvYJtO4RF9cvHuC1R17k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPKV1S%2Fbtq2DEN9XoB%2FudkvYJtO4RF9cvHuC1R17k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;377&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;branch는 특정한 target address가 있다.&lt;br /&gt;branch instruction의 32bit은 4개의 영역으로 나뉘게 된다&lt;br /&gt;op, rs, rt, constant or address&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;branch에서 이동할 target address를 수식을 통해 계산할 수 있다.&lt;br /&gt;이를 PC-relative addressing이라 한다.&lt;br /&gt;공식은 아래와 같다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PC(Program Counter) + offset(constant or address) &amp;times; 4&lt;/b&gt;&lt;br /&gt;Program Counter의 경우에는 이미 프로그램이 실행하고 있을 시&lt;br /&gt;다음 address를 가리키고 있으므로 이미 4byte 증가해있다.&lt;br /&gt;이를 고려하여 계산을 해야 한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;3. Jump Addressing&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;331&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTtUPG/btq2D3tsnmc/uHoHqnGPR917b8fG82hHI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTtUPG/btq2D3tsnmc/uHoHqnGPR917b8fG82hHI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTtUPG/btq2D3tsnmc/uHoHqnGPR917b8fG82hHI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTtUPG%2Fbtq2D3tsnmc%2FuHoHqnGPR917b8fG82hHI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;527&quot; height=&quot;331&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;331&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Jump instruction의 32 bit는 2영역으로 나뉘게 된다.&lt;br /&gt;op, address&lt;br /&gt;opcode는 항상 6bit이며 address는 26bit이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이런 방식의 addressing을 (Pseudo)Direct jump addressing 이라고 한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;address는 32bit이다.&lt;br /&gt;target address는 현재 PC에 들어있는 상위 4bit이 그대로 가져오고(PC의 주소와 JUMP 목적지가 인접할 것이라 가정)&lt;br /&gt;address는 항상 4byte 단위로 움직이기 때문에 하위 2bit는 생략하여 표현이 가능하다.&lt;br /&gt;하위 28bit는 26bit * 4를 하게 되면 28bit가 된다.&lt;br /&gt;그래서 28bit와 4bit를 합쳐 target address를 구성하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;4. Target Addressing Example&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w95dE/btq2CEBbtSs/thL6a1N5hrbg8ZK3CFX9F1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w95dE/btq2CEBbtSs/thL6a1N5hrbg8ZK3CFX9F1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w95dE/btq2CEBbtSs/thL6a1N5hrbg8ZK3CFX9F1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw95dE%2Fbtq2CEBbtSs%2FthL6a1N5hrbg8ZK3CFX9F1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;527&quot; height=&quot;287&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Loop가 80000번지에 위치해있고 그림과 같이 instruction들이 배치 되어있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;instruction간 주소는 4의 배수이다.&lt;br /&gt;&lt;b&gt;bne $t0, $s5, Exit&lt;/b&gt;의 constant or address 영역은 2이다.&lt;br /&gt;이 constant or address 영역은 branch instruction의 도착점이 PC에서 일정 거리 이내이 있을거라는&lt;br /&gt;가정 하에 PC에서 목적지까지의 차이를 저장한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PC는 항상 다음 instruction의 주소를 가리킨다.&lt;br /&gt;즉, 현재 &lt;b&gt;bne $t0, $s5, Exit&lt;/b&gt;의 주소는 80012이고 그다음 번지는 80016이다.&lt;br /&gt;80016에서 다음 2번째가 바로 Exit의 주소이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;즉, target address의 공식에 대입하게 되면 80016 + (2 * 4) = 80024가 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;j Loop&lt;/b&gt;의 address영역은 20000이다.&lt;br /&gt;공식에 대입하게 되면 20000 * 4 = 80000이 된다.&lt;br /&gt;(Pseudo)Direct jump addressing 또한 PC에서의 앞 4bit를 가져온다.&lt;br /&gt;PC에 저장된 주소와 jump 목적지가 인접할 것이라고 가정한다.&lt;br /&gt;즉, 상위 4bit은 0000 이므로 80000이 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;lw $t0, 0($t1)&lt;/b&gt; 의 constant는 ($t1)의 앞에 붙어있는 값이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;5. Branching Far Away&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qUuvK/btq2BC4FliQ/IVoZpZaKKTAuKCD2PJPl50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qUuvK/btq2BC4FliQ/IVoZpZaKKTAuKCD2PJPl50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qUuvK/btq2BC4FliQ/IVoZpZaKKTAuKCD2PJPl50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqUuvK%2Fbtq2BC4FliQ%2FIVoZpZaKKTAuKCD2PJPl50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;256&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Branch는 때때로 Branc target이 너무 멀리 있어 16bit offset값을 넘을 때가 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이런 경우 어셈블러는 &lt;b&gt;beq $s0,$s1, L1&lt;/b&gt; 을 아래와 같이 바꿔준다.&lt;br /&gt;&lt;b&gt;bne $s0,$s1, L2&lt;br /&gt;j L1&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Branch instruction 대신 jump instruction을 쓰게 된다.&lt;br /&gt;jump는 26bit를 커버하기 때문에 훨씬 멀리 있는 곳 까지 jump 할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;6. Addressing Mode Summary&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;419&quot; data-origin-height=&quot;485&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNTEYW/btq2zfoAWDX/gFH2y0fllHf0P9qV3Rn530/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNTEYW/btq2zfoAWDX/gFH2y0fllHf0P9qV3Rn530/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNTEYW/btq2zfoAWDX/gFH2y0fllHf0P9qV3Rn530/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNTEYW%2Fbtq2zfoAWDX%2FgFH2y0fllHf0P9qV3Rn530%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;419&quot; height=&quot;485&quot; data-origin-width=&quot;419&quot; data-origin-height=&quot;485&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;MIPS에는 5가지 addressing mode가 존재한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;immedate addressing : addi ...&lt;/li&gt;
&lt;li&gt;register addressing : R-type ...&lt;/li&gt;
&lt;li&gt;base addressing : lw, sw ...&lt;/li&gt;
&lt;li&gt;PC-relative addressing : branch ...&lt;/li&gt;
&lt;li&gt;(Pseudo)Direct jump addressing: jump ...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;7. Synchronization&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1OVZh/btq2CDoHJQn/1kkiAIMGC8fzzvc1vdzJXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1OVZh/btq2CDoHJQn/1kkiAIMGC8fzzvc1vdzJXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1OVZh/btq2CDoHJQn/1kkiAIMGC8fzzvc1vdzJXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1OVZh%2Fbtq2CDoHJQn%2F1kkiAIMGC8fzzvc1vdzJXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;498&quot; height=&quot;310&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;최근에 나온 프로세서는 멀티코어이다.&lt;br /&gt;이럴 경우 서로다른 코어가 하나의 메모리 공간을 공유할 수 있다.&lt;br /&gt;Race condtion이 발생할 수 있기 때문에 엑세스 순서를 잘 지켜줘야 한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이런 문제 해결을 위해 H/W의 도움이 필요하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;대표적인 예로 Atomic read/write memory가 있다.&lt;br /&gt;Atomic은 어떤 operation을 할때 중간에 인터럽트가 발생하지 않는 것이다.&lt;br /&gt;한번 명령어가 시작하면 인터럽트 없이 명령어를 완료하는 것이다.&lt;br /&gt;이런 경우 read와 write사이에 다른 location에 대한 엑세스를 허용하지 않는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;spin lock을 구현할 때 Atomic read/write memory operation 을 지원해주는 single instruction을 사용한다.&lt;br /&gt;atomic swap of register&lt;br /&gt;atomic pair&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이런식으로 인터럽트가 발생하지 않도록 해준다.&lt;br /&gt;즉, 2개의 &lt;br /&gt;이 하나로 되게끔 해주는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7-1. Synchronization in MIPS&lt;/h2&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IPRtX/btq2E91ehud/dZ4GHVl8OGgvk6rNEoUdo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IPRtX/btq2E91ehud/dZ4GHVl8OGgvk6rNEoUdo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IPRtX/btq2E91ehud/dZ4GHVl8OGgvk6rNEoUdo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIPRtX%2Fbtq2E91ehud%2FdZ4GHVl8OGgvk6rNEoUdo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;298&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;MIPS에서는 Load linked: ll rt, offset(rs) 명령어가 Atomic operation이다.&lt;br /&gt;이런 명령어를 사용해서 Synchronization 명령어를 만들 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;8. Translation and Startup&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czUcRA/btq2ClIzrLY/dk0egPiYwGbgpKRzm2z220/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czUcRA/btq2ClIzrLY/dk0egPiYwGbgpKRzm2z220/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czUcRA/btq2ClIzrLY/dk0egPiYwGbgpKRzm2z220/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczUcRA%2Fbtq2ClIzrLY%2Fdk0egPiYwGbgpKRzm2z220%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;618&quot; height=&quot;358&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;C언어를 작성하면 컴파일러는 C코드를 어셈블리 코드로 바꿔주게 된다.&lt;br /&gt;어셈블러는 다시 기계어로 만들어 준다.&lt;br /&gt;대부분 컴파일러는 이 2가지 step을 일괄적으로 처리한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이 프로그램에서 사용된 라이브러리와 새로 코딩한 프로그램을 합쳐서 실행파일을 만들어주는 linker가 존재한다.&lt;br /&gt;실행 파일이 만들어진 다음에는 프로그램을 실행해야한다.(저장장치 - 메모리로 옮김)&lt;br /&gt;이것을 loader가 담당한다.&lt;br /&gt;loader는 프로그램을 메모리에 올려준다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;linker time에 object code가 실행파일로 들어오는 것을 Static linking이라고 한다.&lt;br /&gt;이거와 반대되는 개념이 Dynamic linking이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;9. Assembler Pseudoinstructions&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJ1mBy/btq2yaOTXYu/9lg86uKy7KBj2snvU2YK60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJ1mBy/btq2yaOTXYu/9lg86uKy7KBj2snvU2YK60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJ1mBy/btq2yaOTXYu/9lg86uKy7KBj2snvU2YK60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJ1mBy%2Fbtq2yaOTXYu%2F9lg86uKy7KBj2snvU2YK60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;266&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;MIPS 어셈블러 같은 경우에는 Pseudoinstructions이 존재한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;실제 MIPS에 명령은 없지만 어셈블러에서 사용할 수 있는 가짜 명령어다.&lt;br /&gt;이런 경우 어셈블러가 해당되는 실제 MIPS명령어로 자동으로 바꿔주게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;예를 들어 move와 같은 명령어가 있을 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;at은 MIPS에서 사용할 수 없지만 어셈블러에서만 사용할 수 있는 레지스터이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;10. Producing an Object Module&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRiiri/btq2yol0MBs/mWJzfJr9uFcvlhejN3kBuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRiiri/btq2yol0MBs/mWJzfJr9uFcvlhejN3kBuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRiiri/btq2yol0MBs/mWJzfJr9uFcvlhejN3kBuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRiiri%2Fbtq2yol0MBs%2FmWJzfJr9uFcvlhejN3kBuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;304&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;어셈블러가 프로그램을 기계어로 변환시켜 준다.&lt;br /&gt;기계어로 변환할 때 object 모듈은 아래 정보를 가지고 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Header : object의 내용&lt;/li&gt;
&lt;li&gt;Text segment : instruction&lt;/li&gt;
&lt;li&gt;Static data segment : 전역 변수&lt;/li&gt;
&lt;li&gt;Relocation info : 프로그램이 로딩 됐을때 그것과 관련된 절대적인 주소를 가지고 있음&lt;/li&gt;
&lt;li&gt;Symbol table : global 변수와 함수&lt;/li&gt;
&lt;li&gt;Debug info : 소스코드 정보&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;11. Linking Object Modules&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbCWiq/btq2zeXwYDs/j9kTqsRNDBgjVPFx0WqHI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbCWiq/btq2zeXwYDs/j9kTqsRNDBgjVPFx0WqHI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbCWiq/btq2zeXwYDs/j9kTqsRNDBgjVPFx0WqHI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbCWiq%2Fbtq2zeXwYDs%2Fj9kTqsRNDBgjVPFx0WqHI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;296&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;위 object module을 묶어서 실제 실행파일을 만들어야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;segment들을 합친다.&lt;/li&gt;
&lt;li&gt;Label들을 해결해준다.&lt;/li&gt;
&lt;li&gt;location-dependent한 정보를 위치에 맞춰주고 외부참조도 해결해준다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;relocating loader에 의해 고쳐질 수 있는 location dependencies는 그대로 둔다.&lt;br /&gt;하지만 현재 우리가 사용하고 있는 컴퓨터는 가상 메모리를 사용하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;가상 메모리는 모든 프로그램이 같은 메모리 영역을 사용하기 때문에 location dependencies 정보는 필요 없다.&lt;br /&gt;즉, 가상 메모리의 절대 주소값을 쓰면 되는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;12. Loading a Program&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dk0mho/btq2AFAxP1w/wW44wdkSuYg0nBhWRyS1Bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dk0mho/btq2AFAxP1w/wW44wdkSuYg0nBhWRyS1Bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dk0mho/btq2AFAxP1w/wW44wdkSuYg0nBhWRyS1Bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdk0mho%2Fbtq2AFAxP1w%2FwW44wdkSuYg0nBhWRyS1Bk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;511&quot; height=&quot;308&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;실행 파일을 디스크에서 메모리로 올려야 한다.&lt;br /&gt;실행파일의 Header를 읽은 후 segment의 크기를 결정해야 한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이후 가상 메모리 주소를 만든 후 데이터를 메모리 공간에 올려준다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;그 다음 stack을 위한 argument를 설정하고 register를 초기화 한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;마지막으로 시작 routine으로 jump한다.&lt;br /&gt;C언어 같은 경우는 main으로 jump하게 되는 것이다.&lt;br /&gt;프로그램이 끝나게 되면 exit 시스템콜을 실행한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;13. Dynamic Linking&lt;/h1&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H7YWT/btq2y4guAGT/tKAKBRlfIU6Ef9IZ9zKO6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H7YWT/btq2y4guAGT/tKAKBRlfIU6Ef9IZ9zKO6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H7YWT/btq2y4guAGT/tKAKBRlfIU6Ef9IZ9zKO6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH7YWT%2Fbtq2y4guAGT%2FtKAKBRlfIU6Ef9IZ9zKO6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;513&quot; height=&quot;198&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Dynamic Linking은 해당 함수가 불려진 경우에만 link와 load를 하는 것이다.&lt;br /&gt;static linking은 함수가 불려지든 안불려지든 실행파일에 집어 넣게된다.&lt;br /&gt;하지만 dynamic은 오직 함수가 사용될때만 link와 load한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;procedure code가 relocatable되도록 작성해야 한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static linking에 비해 Dynamic Linking을 많이 사용하는 이유는&lt;br /&gt;실제 실행되는 것만 사용하기 때문에 실행파일의 크기가 커지는 것을 방지할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;또한 Dynamic Linking은 그 함수에 관련된 코드가 실행파일에 들어가 있는 것이 아닌&lt;br /&gt;Dynamic Linking이 저장되어있는 파일에 별도로 저장되어있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;새로운 라이브러리가 나올때마다 그 파일만 업데이트 하면되므로 프로그램을 컴파일 할 필요가 없다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;라이브러리를 배포 및 사용할때 Dynamic Linking이 되는 라이브러리를 많이 사용하게 된다.&lt;br /&gt;static linking보다 효율적이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;14. Lazy Linkage&lt;/h2&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btdLus/btq2EhrGDM2/HXsLJoZfLHsHm9CNPvDkqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btdLus/btq2EhrGDM2/HXsLJoZfLHsHm9CNPvDkqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btdLus/btq2EhrGDM2/HXsLJoZfLHsHm9CNPvDkqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtdLus%2Fbtq2EhrGDM2%2FHXsLJoZfLHsHm9CNPvDkqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;424&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;하지만 Dynamic Linking은 처음 Dynamic Linking이 되는 함수를 사용하면&lt;br /&gt;위와 같이 복잡한 과정을 거치게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;기존 함수는 타겟이 있는 코드로 바로 가지만 Dynamic Linking같은 경우에는&lt;br /&gt;어떤 data에 가게되고 data에는 Dynamic Linking과 관련된 위치정보가 있다.&lt;br /&gt;이 위치 정보를 사용해서 해당 코드가 있는 곳으로 가게된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;그리고 그 코드에서 실제로 함수가 있는 코드로 Jump하게 된다.&lt;br /&gt;그리고 해당 코드의 실행이 끝나면 다시 처음으로 돌아간다.&lt;br /&gt;그림의 예시에서 실제 DLL Dynamic Linking으로 정의된 함수는 위 과정에서 마지막 코드에 있는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;물론 한번 불려지게 되면 이후에는 data에 위치에 DLL 시작주소를 바로 저장해서&lt;br /&gt;위 과정을 거치지 않고 바로 실행하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Static linking은 위 과정을 거치지 않는다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;우리가 함수를 정의하면 모든 함수가 항상 불려지지 않고 Data에 의존적으로 불려지게 된다.&lt;br /&gt;그러므로 불려지지 않는 함수까지 위 과정을 미리 거치는 것은 불필요하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;그래서 불려지는 함수에 대해서만 위 과정을 거치는 것이다.&lt;br /&gt;물론 위 과정들을 거치기 때문에 Dynamic Linking으로 구성된 함수를 사용하면 성능은 떨어지게 된다.&lt;br /&gt;그러나 실행파일의 크기가 커지지 않고 새로운 라이브러리를 사용하더라도&lt;br /&gt;실행파일을 다시 컴파일 하지 않는 장점이 있기 때문에&lt;br /&gt;라이브러리 같은 경우에는 Dynamic Linking으로 정의돼서 많이 사용된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>Computer Science/컴퓨터 구조</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/19</guid>
      <comments>https://immigrationssu.tistory.com/entry/8-Instructions-Language-of-the-Computer-4#entry19comment</comments>
      <pubDate>Wed, 14 Apr 2021 22:54:35 +0900</pubDate>
    </item>
    <item>
      <title>7. Instructions: Language of the Computer 3</title>
      <link>https://immigrationssu.tistory.com/entry/7-Instructions-Language-of-the-Computer-3</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 최규상 교수님 컴퓨터구조 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;참고 : 컴퓨터 구조 및 설계 - David A. Patterson,John L. Hennessy&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=f64448266743ced9&quot;&gt;http://www.kocw.net/home/cview.do?lid=f64448266743ced9&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. Six steps in Execution of a procedure(Procedure Calling)&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rnfDd/btq2iVcfZJa/cGhxeQyU1E1EFEur780PJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rnfDd/btq2iVcfZJa/cGhxeQyU1E1EFEur780PJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rnfDd/btq2iVcfZJa/cGhxeQyU1E1EFEur780PJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrnfDd%2Fbtq2iVcfZJa%2FcGhxeQyU1E1EFEur780PJ1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGCN82/btq2nhMpx5O/qB7kV6jwuSJLp0m7FKYYg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGCN82/btq2nhMpx5O/qB7kV6jwuSJLp0m7FKYYg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGCN82/btq2nhMpx5O/qB7kV6jwuSJLp0m7FKYYg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGCN82%2Fbtq2nhMpx5O%2FqB7kV6jwuSJLp0m7FKYYg1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;procedure 실행의 6단계를 뜻한다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;caller는 어떠한 함수를 부르는 것이고 callee는 불리여지는 함수를 뜻한다.&lt;br&gt; claller는 callee가 엑세스 할 수 있는 곳에 argument를 가져다 놓게 된다.&lt;br&gt; MIPS의 argument register는 $a0~$a3가 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;caller는 callee로 프로그램의 control을 넘기게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;callee는 필요한 메모리 공간을 할당 받게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;callee가 해야될 일을 하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;callee가 일을 다한 후에는 caller가 엑세스할 수 있는 위치에 return value를 저장하게 된다.&lt;br&gt; MIPS에서는 return value로 $v0, $v1이 있으며 callee가 해당 register를 통해 caller로 return value를 전달하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;callee가 다시 caller에게 프로그램의 control을 넘기게 된다.&lt;br&gt; 이 때 retrun address를 알고 있어야 한다.&lt;br&gt; return address는 $ra register에 저장되어 있다.&lt;br&gt; 이 값을 통해 caller로 프로그램 control이 넘어가게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. Register Usage&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCIqXf/btq2hJDE2Ch/ngjpgHSzTFUY5JxxHMI6r1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCIqXf/btq2hJDE2Ch/ngjpgHSzTFUY5JxxHMI6r1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCIqXf/btq2hJDE2Ch/ngjpgHSzTFUY5JxxHMI6r1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCIqXf%2Fbtq2hJDE2Ch%2FngjpgHSzTFUY5JxxHMI6r1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;MIPS에서 제공되는 레지스터이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3. Procedure Call Instructions&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhqzYU/btq2npQ6SNq/s8iGOIqp0OwHaXg5bZJCPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhqzYU/btq2npQ6SNq/s8iGOIqp0OwHaXg5bZJCPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhqzYU/btq2npQ6SNq/s8iGOIqp0OwHaXg5bZJCPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhqzYU%2Fbtq2npQ6SNq%2Fs8iGOIqp0OwHaXg5bZJCPk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Procedure Call관련 명령어이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;jal ProcedureLabel&lt;br&gt;이 명령어는 2가지를 동시에 하게 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jal 다음 명령어의 주소를 ra에 넣음&lt;/li&gt;
&lt;li&gt;해당 ProcedureLabel의 target address로 점프 하게 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
그 다음 callee로 갔으니 caller로 가야한다.
&lt;br/&gt;

&lt;p&gt;jr $ra&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$ra register에 들어있는 값으로 프로그램 control이 바뀌게 된다.&lt;/li&gt;
&lt;li&gt;$ra에 값을 Program Counter에 저장하게 되며 $ra에 있는 값으로 점프하게 되는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3-1. Leaf Procedure Example&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dXXn7Y/btq2np4C2yQ/HGuzgDdAA2HUWsCCUXYunK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dXXn7Y/btq2np4C2yQ/HGuzgDdAA2HUWsCCUXYunK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dXXn7Y/btq2np4C2yQ/HGuzgDdAA2HUWsCCUXYunK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXXn7Y%2Fbtq2np4C2yQ%2FHGuzgDdAA2HUWsCCUXYunK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Leaf Procedure는 해당 함수에서 다른 함수를 부르지 않는 것을 뜻한다.&lt;br&gt;해당 C코드를 MIPS코드로 컴파일 하게 되면 아래와 같다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KrsQ7/btq2hs91d5X/eESzRtWNHkKMnOWykzHnOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KrsQ7/btq2hs91d5X/eESzRtWNHkKMnOWykzHnOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KrsQ7/btq2hs91d5X/eESzRtWNHkKMnOWykzHnOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKrsQ7%2Fbtq2hs91d5X%2FeESzRtWNHkKMnOWykzHnOK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;addi $sp, $sp, -4 (allocation)&lt;br&gt;스택 포인터를 4만큼 감소시킨다.&lt;br&gt;스택은 위에서 부터 아래로 감소하게 된다.&lt;br&gt;-4를 한다는 것은 4byte만큼 스택에 할당한다는 뜻이다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sw $s0, 0($sp)&lt;/strong&gt;&lt;br&gt;할당 된 공간에 기존에 $s0 값이 어떤 값이 저장되있을 수도 있으니 $s0 레지스터를 스택에 저장해 놓는다.&lt;br&gt;그리고 이 $s0를 f변수로 사용한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;add $t0, $a0, $a1&lt;/strong&gt;&lt;br&gt;그 다음 $a0와 $a1을 더한 후 $t0에 넣는다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;add $t1, $a2, $a3&lt;/strong&gt;&lt;br&gt;그리고 $a2와 $a3을 더해서 $t1에 넣는다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sub $s0, $t0, $t1&lt;/strong&gt;&lt;br&gt;그리고 나서 $t1과 $t0를 뺀 후 $s0에 넣는다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;add $v0, $s0, $zero&lt;/strong&gt;&lt;br&gt;연산된 결과 값($s0)을 zero와 더한 후 $v0에 넣는다.&lt;br&gt;move 명령어와 같은 역할을 하게 된다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;lw $s0, 0($sp)&lt;/strong&gt;&lt;br&gt;스택에 있는 값을 다시 $s0에 넣는다.&lt;br&gt;$s0를 로컬 변수로 사용했으며 다 사용한 후에는 원래 값으로 복원시켜 놓아야 한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;addi $sp, $sp, 4 (deallocation)&lt;/strong&gt;&lt;br&gt;그 다음 4byte만큼 할당받은 메모리를 반납해야한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;jr $ra&lt;/strong&gt;&lt;br&gt;마지막으로 $ra에있는 레지스터 값으로 점프하게 된다.&lt;/p&gt;
&lt;br/&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;caller가 jal leaf_example라는 명령어를 실행한다.&lt;br&gt;이 순간에 jal 명령어 다음에 오는 명령어 주소가 $ra에 들어가게 된다.&lt;br&gt;그 다음 leaf_example를 다 실행한 후 $ra에 있는 주소로 점프하게 되는 것이다.&lt;br&gt;즉, jal leaf_example 다음 명령어가 실행 되는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;3-2. Non-Leaf Procedures&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v52GB/btq2hKieClz/wlYriWZxSTyukNKdcV1NNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v52GB/btq2hKieClz/wlYriWZxSTyukNKdcV1NNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v52GB/btq2hKieClz/wlYriWZxSTyukNKdcV1NNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv52GB%2Fbtq2hKieClz%2FwlYriWZxSTyukNKdcV1NNk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Leaf Procedures는 그 함수에서 다른 함수를 호출하지 않아 함수를 처리하는데 아주 수훨하다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;하지만 하나의 함수가 또 다른 함수를 부를 수 있다.&lt;br&gt;이런 경우는 처리가 복잡해진다.&lt;br&gt;caller가 그 안에서 다른 것을 부르게 되면 $ra레지스터 값을 다른 곳에 저장해두어야 한다.&lt;br&gt;또한 arguments나 temporaries 등 또한 스택에 저장해두어야 한다.&lt;br&gt;그 다음 callee에서 caller로 온 후 스택에 저장된 값을 복원해야 한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Non-Leaf Procedures는 Leaf Procedures보다 처리가 복잡하다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h3&gt;3-2-1. Non-Leaf Procedure Example&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAarAr/btq2hsIS6k4/2Lctg5hJ9TKs4I0is1DX41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAarAr/btq2hsIS6k4/2Lctg5hJ9TKs4I0is1DX41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAarAr/btq2hsIS6k4/2Lctg5hJ9TKs4I0is1DX41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAarAr%2Fbtq2hsIS6k4%2F2Lctg5hJ9TKs4I0is1DX41%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;C코드는 Leaf Procedure와 비슷하지만 어셈블리 코드는 매우 복잡하다.&lt;br&gt;MIPS 코드로 컴파일 한것은 아래와 같다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEsiPw/btq2lq3PzSv/kFo663VSragMxK2OKSjZu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEsiPw/btq2lq3PzSv/kFo663VSragMxK2OKSjZu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEsiPw/btq2lq3PzSv/kFo663VSragMxK2OKSjZu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEsiPw%2Fbtq2lq3PzSv%2FkFo663VSragMxK2OKSjZu1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;*fact:&lt;br&gt;  addi $sp, $sp, -8&lt;br&gt;  sw $ra, 4($sp)&lt;br&gt;  sw $a0, 0($sp)&lt;/strong&gt;&lt;br&gt;스택을 -8을 하게 된다.&lt;br&gt;2가지 값을 저장하기 위해서이다.&lt;br&gt;바로 retrun address와 argument이다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;slti $t0, $a0, 1&lt;/strong&gt;&lt;br&gt;$a0와 1을 비교한다.&lt;br&gt;$a0가 1보다 작으면 $t0가 1이 된다.&lt;br&gt;만약 $a0가 1보다 크다면 $t0는 0이 된다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;beq $t0, $zero, L1&lt;/strong&gt;&lt;br&gt;$t0와 zero가 같으면 L1 label로 점프하게 된다.&lt;br&gt;그러나 $t0가 zero와 같지 않다면 그 다음 명령어로 점프하게 된다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;addi $v0, $zero, 1&lt;/strong&gt;&lt;br&gt;$a0가 1보다 작다면 $t0가 0이 되어서 $t0와 zero가 같아지고 해당 명령어를 실행하게 된다.&lt;br&gt;1을 $v0에 넣게 된다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;addi $sp, $sp, 8&lt;/strong&gt;&lt;br&gt;스택 값을 다시 8만큼 증가한다.&lt;br&gt;할당 받은 것을 deallocation하기 위함이다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;jr $ra&lt;/strong&gt;&lt;br&gt;그다음 $ra의 있는 값으로 점프하게 된다.&lt;br&gt;만약 L1 label을 실행했다면 &lt;strong&gt;lw $a0, 0($sp)&lt;/strong&gt; 명령어를 실행하게 되는 것이다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;L1 :&lt;br&gt;  addi $a0, $a0, -1&lt;/strong&gt;&lt;br&gt;만약 $a0의 값이 2라고 가정하면 해당 명령어를 실행하게 된다.&lt;br&gt;$a0의 값을 1만큼 감소한다.&lt;br&gt;그리고 그 다음 명령어를 실행한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;jal fact&lt;/strong&gt;&lt;br&gt;fact label로 점프한다.&lt;br&gt;해당 명령어를 실행할 때 이 명령어의 다음 명령어가 있는 메모리 주소 값이 $ra register로 들어가게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;lw $a0, 0($sp)&lt;br&gt;  lw $ra, 4($sp)&lt;br&gt;  addi $sp, $sp, 8&lt;br&gt;  mul $v0, $a0, $v0&lt;br&gt;  jr $ra&lt;/strong&gt;&lt;br&gt;해당 fact label을 부른 caller로 가게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;4. Local Data on the Stack&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vDP56/btq2kraN49S/c7wkFKKooSOwVa9BrSZqZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vDP56/btq2kraN49S/c7wkFKKooSOwVa9BrSZqZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vDP56/btq2kraN49S/c7wkFKKooSOwVa9BrSZqZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvDP56%2Fbtq2kraN49S%2Fc7wkFKKooSOwVa9BrSZqZK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;실제 프로그램에서 함수를 사용할 때 메모리가 어떤 식으로 할당 되는지 보여주는 그림이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;frame pointer와 stack pointer가 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;stack pointer는 현재 스택에 있는 top의 위치를 가리키는 포인터이다.(register)&lt;br&gt;&lt;br/&gt;&lt;br&gt;하나의 함수를 실행할 때 할당되는 메모리 공간을 activation record라고 부른다.&lt;br&gt;activation record의 처음 시작하는 위치를 가리키는 것을 frame pointer라 한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;activation record의 시작을 가리키는 것을 frame pointer, 끝을 가리키는 것을 stack pointer라 한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;activation record는 argument, return address, 필요한 register, 로컬 변수들이 저장 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;함수가 끝나게 되면 activation record는 deallocation이 된다.&lt;br&gt;그렇게 되면 frame pointer와 stack pointer는 조정이 된다.&lt;br&gt;다시 바로 위에 activation record 관련 시작 주소와 끝 주소를 가리키게 된다.&lt;/p&gt;
&lt;h1&gt;5. Memory Layout&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CoxAX/btq2iVQRy8d/IX9JNgv15tb5YgKP6sxj8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CoxAX/btq2iVQRy8d/IX9JNgv15tb5YgKP6sxj8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CoxAX/btq2iVQRy8d/IX9JNgv15tb5YgKP6sxj8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCoxAX%2Fbtq2iVQRy8d%2FIX9JNgv15tb5YgKP6sxj8k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;실제 우리가 사용하는 메모리는 그림과 같은 구조로 할당이 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;맨 아래 주소 공간은 예약 되어있다.&lt;br&gt;그 위에는 Text가 저장 된다.&lt;br&gt;Text는 명령어들이다.(프로그램 코드)&lt;br&gt;&lt;br/&gt;&lt;br&gt;그리고 그 다음 전역변수인 static 변수가 저장된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;메모리 제일 끝 공간을 stack이라고 한다.&lt;br&gt;이 공간에는 activation record들이 할당이 된다&lt;br&gt;&lt;br/&gt;&lt;br&gt;그리고 동적데이터(malloc)가 할당되는 heep이 있다.&lt;br&gt;static data 위에 있게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;stack은 아래 아래방향으로 할당되며 Danymic data는 위 방향으로 할당이 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;프로그램을 실행하다보면 stack overflow가 생길때가 있다.&lt;br&gt;이 경우는 stack이 계속 증가하여 heap공간을 침범하게 되면 stack overflow가 발생하게 되는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Program Coutner값은 Text 안에서 움직이게 된다.&lt;br&gt;global pointer는 static data를 엑세스하기 쉽게 하기 위해서 사용되는 포인터로&lt;br&gt;Text가 할당이 되고 그 위를 가리키게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;MIPS에서는 static data가 0x1000 ffff와 0x1000 0000사이에 할당된다.&lt;br&gt;global pointer는 해당 값의 중간 값을 갖게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;6. Character Data&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XrviX/btq2gRWkLgt/U7K0QDXkEXTgMOPKjPpzx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XrviX/btq2gRWkLgt/U7K0QDXkEXTgMOPKjPpzx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XrviX/btq2gRWkLgt/U7K0QDXkEXTgMOPKjPpzx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXrviX%2Fbtq2gRWkLgt%2FU7K0QDXkEXTgMOPKjPpzx0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;char은 byte이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;처음에는 알파벳만 저장할 수 있도록 정의가 되었다.&lt;br&gt;하지만 아시아는 다양한 문자들이 있어서 Unicode라는 것이 제정이 된다.&lt;br&gt;유니코드는 32bit Character set이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;ASCII, Latin-1은 문자를 무조건 8bit로 표현한다.&lt;br&gt;하지만 variable-length(UTF-8, UTF-16)는 여러 byte를 사용해서 표현할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;7. Byte/Halfword Operations&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCzNbR/btq2oSr5xq5/62Npb09pkaaRiubStnRyVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCzNbR/btq2oSr5xq5/62Npb09pkaaRiubStnRyVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCzNbR/btq2oSr5xq5/62Npb09pkaaRiubStnRyVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCzNbR%2Fbtq2oSr5xq5%2F62Npb09pkaaRiubStnRyVk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;1byte, 2byte데이터를 엑세스할 때가 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;lb는 1byte만큼 로딩하며 lbu는 unsigend로 로딩한다.&lt;br&gt;lb와 lbu는 byte 또는 2byte를 읽는다 하더라도 32bit로 extend를 해서 레지스터에 넣게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;sb는 1byte만큼 store한다.&lt;br&gt;이런 경우 rightmost에 저장이 된다.&lt;br&gt;혹은 halfword에 저장이 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;7-1. String Copy Example&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DrQHf/btq2hsvos7v/rYSAv6SYEXOMBLeS3VwWpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DrQHf/btq2hsvos7v/rYSAv6SYEXOMBLeS3VwWpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DrQHf/btq2hsvos7v/rYSAv6SYEXOMBLeS3VwWpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDrQHf%2Fbtq2hsvos7v%2FrYSAv6SYEXOMBLeS3VwWpK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;strcpy는 Leaf Procedure이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;String에서 null이 존재하면 String은 끝이 나게 된다.&lt;br&gt;해당 C코드를 MIPS 코드로 컴파일하게 되면 아래와 같다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1fkTl/btq2kCpY5AR/4qF2k7pDZOT4nvDGJtpT5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1fkTl/btq2kCpY5AR/4qF2k7pDZOT4nvDGJtpT5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1fkTl/btq2kCpY5AR/4qF2k7pDZOT4nvDGJtpT5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1fkTl%2Fbtq2kCpY5AR%2F4qF2k7pDZOT4nvDGJtpT5K%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;addi $sp, $sp, -4&lt;/strong&gt;&lt;br&gt;i 로컬 변수를 사용하기 위해 스택을 4만큼 감소시킨다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sw $s0, 0($sp)&lt;/strong&gt;&lt;br&gt;거기에 기존에 있던 $s0값을 저장한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;L1 :&lt;br&gt;  add $t1, $s0, $a1&lt;/strong&gt;&lt;br&gt;그 다음 $s0에다가 $a1을 더하게 된다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;lbu $t2, 0($t1)&lt;/strong&gt;&lt;br&gt;1byte만큼 읽는다.&lt;br&gt;즉, y[i] index 값을 $t2에 넣는 것이다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;add $t3, $s0, $a0&lt;/strong&gt;&lt;br&gt;x[i]의 주소를 계산한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sb $t2, 0($t3)&lt;/strong&gt;&lt;br&gt;y[i]의 값을 x[i]에 저장한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;beq $t2, $zero, L2&lt;/strong&gt;&lt;br&gt;y[i]가 0과 같은지 아닌지를 체크한다.&lt;br&gt;같다면 L2레이블로 점프하며&lt;br&gt;같지 않다면 다음 명령어를 실행한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;addi $s0, $s0, 1&lt;/strong&gt;&lt;br&gt;i 값을 1만큼 증가한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;j L1&lt;/strong&gt;&lt;br&gt;L1으로 점프한다.&lt;br&gt;점프는 무조건 실행하게 된다.&lt;br&gt;해당 라인은 loop에 해당된다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;L2 :&lt;br&gt;  lw $s0, 0($sp)&lt;/strong&gt;&lt;br&gt;기존에 $s0에 있던 값을 복원한다.&lt;/p&gt;
&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;addi $sp, $sp, 4&lt;/strong&gt;&lt;br&gt;스택값을 조정한다.&lt;/p&gt;
&lt;br/&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;jr $ra&lt;/strong&gt;&lt;br&gt;caller로 점프하게 된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/컴퓨터 구조</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/18</guid>
      <comments>https://immigrationssu.tistory.com/entry/7-Instructions-Language-of-the-Computer-3#entry18comment</comments>
      <pubDate>Sun, 11 Apr 2021 21:44:35 +0900</pubDate>
    </item>
    <item>
      <title>6. Instructions: Language of the Computer 2</title>
      <link>https://immigrationssu.tistory.com/entry/6-Instructions-Language-of-the-Computer-2</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 최규상 교수님 컴퓨터구조 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;참고 : 컴퓨터 구조 및 설계 - David A. Patterson,John L. Hennessy&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=4e4c594ab2a7a659&quot;&gt;http://www.kocw.net/home/cview.do?lid=4e4c594ab2a7a659&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. Unsigned Binary Integers&lt;/h1&gt;
&lt;p&gt;컴퓨터에서는 2진수를 사용한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bT7SE6/btq2hCYgDym/9IRfcuIRhrHjnExoiusdLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bT7SE6/btq2hCYgDym/9IRfcuIRhrHjnExoiusdLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bT7SE6/btq2hCYgDym/9IRfcuIRhrHjnExoiusdLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbT7SE6%2Fbtq2hCYgDym%2F9IRfcuIRhrHjnExoiusdLk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;n비트로 되어있는 숫자는 위와 같이 표현한다.&lt;br&gt;범위는 0 to +2ⁿ – 1 이다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHITm3/btq2gKphplo/OlJH3HeUQXacLrTG7a6MyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHITm3/btq2gKphplo/OlJH3HeUQXacLrTG7a6MyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHITm3/btq2gKphplo/OlJH3HeUQXacLrTG7a6MyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHITm3%2Fbtq2gKphplo%2FOlJH3HeUQXacLrTG7a6MyK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;공식의 예로는 위와 같다.&lt;br&gt;0부터 4,294,967,295까지 표현이 가능하다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. 2s-Complement Signed Integers&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uqIk1/btq2gozT9Ts/u0fFNkisxGHPAVLrlzMk90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uqIk1/btq2gozT9Ts/u0fFNkisxGHPAVLrlzMk90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uqIk1/btq2gozT9Ts/u0fFNkisxGHPAVLrlzMk90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuqIk1%2Fbtq2gozT9Ts%2Fu0fFNkisxGHPAVLrlzMk90%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;n비트로 되어있는 숫자는 위와 같이 표현한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDRSZh/btq2ir9M1lJ/xDHEkcNRVxPei9dKfthVL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDRSZh/btq2ir9M1lJ/xDHEkcNRVxPei9dKfthVL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDRSZh/btq2ir9M1lJ/xDHEkcNRVxPei9dKfthVL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDRSZh%2Fbtq2ir9M1lJ%2FxDHEkcNRVxPei9dKfthVL0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;범위는 위와 같다.&lt;br&gt;항상 음수의 최대값이 양수의 최대값보다 하나 더 많다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NpgCo/btq2hY05T95/SOHmXrsvKd2vf6e2X8ajNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NpgCo/btq2hY05T95/SOHmXrsvKd2vf6e2X8ajNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NpgCo/btq2hY05T95/SOHmXrsvKd2vf6e2X8ajNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNpgCo%2Fbtq2hY05T95%2FSOHmXrsvKd2vf6e2X8ajNk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;공식의 예로는 위와 같다.&lt;br&gt;–2,147,483,648부터 +2,147,483,647까지 표현이 가능하다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qxqjB/btq2gXPlSwn/RZaBsjNcSFFl9cjhzBAivK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qxqjB/btq2gXPlSwn/RZaBsjNcSFFl9cjhzBAivK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qxqjB/btq2gXPlSwn/RZaBsjNcSFFl9cjhzBAivK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqxqjB%2Fbtq2gXPlSwn%2FRZaBsjNcSFFl9cjhzBAivK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;2s-Complement Signed Integers를 읽을 때 항상 가장 왼쪽에 있는 LSB(31bit)는 Sign bit이다.&lt;br&gt;0이면 양수이고 1이면 음수이다.&lt;br&gt;음수의 최대 값은 LSB만 1이고 나머지는 모두 0이다.&lt;br&gt;양수의 최대 값은 LSB만 0이고 나머지는 모두 1이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3. Signed Negation&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNxpM6/btq2lCpcAEa/zaffgUlUJQn7kQeBfCa9WK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNxpM6/btq2lCpcAEa/zaffgUlUJQn7kQeBfCa9WK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNxpM6/btq2lCpcAEa/zaffgUlUJQn7kQeBfCa9WK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNxpM6%2Fbtq2lCpcAEa%2FzaffgUlUJQn7kQeBfCa9WK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;부호를 바꿔주는 것이다.&lt;br&gt;각 비트의 값을 반전 시켜주고 해당 값에 1을 더해주는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;4. Sign Extension&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Dydrm/btq2gwLsRP4/7aLoUrUHKiRcDlTlITGXU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Dydrm/btq2gwLsRP4/7aLoUrUHKiRcDlTlITGXU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Dydrm/btq2gwLsRP4/7aLoUrUHKiRcDlTlITGXU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDydrm%2Fbtq2gwLsRP4%2F7aLoUrUHKiRcDlTlITGXU1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;예를 들어 8bit를 16bit 혹은 32bit로 확장하는 것이다.&lt;br&gt;bit의 수를 확장할때도 음수는 그대로 유지되어야 한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;sign bit를 왼쪽에서 부터 확장하면 되며 모든 값을 1로 채운다.&lt;br&gt;unsigned는 0으로 채우면 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;5. Representing Instructions&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GRWjX/btq2iVpheE5/aCy314QZjWQmEXMkgBpBv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GRWjX/btq2iVpheE5/aCy314QZjWQmEXMkgBpBv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GRWjX/btq2iVpheE5/aCy314QZjWQmEXMkgBpBv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGRWjX%2Fbtq2iVpheE5%2FaCy314QZjWQmEXMkgBpBv1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;모든 명령어는 binary로 표현되며 이것을 기계어라고 한다.&lt;br&gt;MIPS 명령어는 32bit로 표현이 된다.&lt;br&gt;32bit 코드지만 MIPS명령어는 operation code의 수가 적다.&lt;br&gt;MIPS는 Format이 별로 없어 간단히 만들 수 있고 높은 성능을 얻을 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;6. MIPS R-format Instructions&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLt7PO/btq2gD4GnM4/1QhE5SiyCg6ttDOEiDkIKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLt7PO/btq2gD4GnM4/1QhE5SiyCg6ttDOEiDkIKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLt7PO/btq2gD4GnM4/1QhE5SiyCg6ttDOEiDkIKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLt7PO%2Fbtq2gD4GnM4%2F1QhE5SiyCg6ttDOEiDkIKK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Arithmetic Instruction이다.&lt;br&gt;32bit은 6개의 영역으로 구성되어있다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;op : Operation 코드이다.&lt;/li&gt;
&lt;li&gt;rs : source register이다.&lt;/li&gt;
&lt;li&gt;rt : target register이다.&lt;/li&gt;
&lt;li&gt;rd : destination register이다.&lt;/li&gt;
&lt;li&gt;shamt : shift amount이다.&lt;/li&gt;
&lt;li&gt;funct : function code를 나타낸다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6-1. R-format Example&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bY7wR8/btq2hDCVNNZ/IaOmSF4l6k3UVVKDG5oFIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bY7wR8/btq2hDCVNNZ/IaOmSF4l6k3UVVKDG5oFIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bY7wR8/btq2hDCVNNZ/IaOmSF4l6k3UVVKDG5oFIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbY7wR8%2Fbtq2hDCVNNZ%2FIaOmSF4l6k3UVVKDG5oFIK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;add의 opcode는 0이다.&lt;br&gt;s1과 s2는 각각 source register와 target register로 가며 t0또한 destination register로 간다.&lt;br&gt;shift 연산이 아니기에 shift amount는 0이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;해당 값들을 bin으로 바꾸면 00000010001100100100000000100000이 되며 16진수로는 0x02324020이다.&lt;br&gt;CPU는 해당 값의 명령어(0x02324020)를 만나면 add $t0, $s1, $s2을 실행한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;7. Hexadecimal&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjhQqW/btq2hrbDj3R/6KFtXOvKi2IqoDOOVbSEy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjhQqW/btq2hrbDj3R/6KFtXOvKi2IqoDOOVbSEy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjhQqW/btq2hrbDj3R/6KFtXOvKi2IqoDOOVbSEy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjhQqW%2Fbtq2hrbDj3R%2F6KFtXOvKi2IqoDOOVbSEy1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;컴퓨터에서 어떤 숫자를 표현할 때 사람들이 이해하기 쉽게하기 위해 16진수로 표현한다.&lt;br&gt;16진수는 4bit를 표현할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;8. MIPS I-format Instructions&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5Lng0/btq2hZeCxqo/s2U7YsngTaTgzi5T1UmBe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5Lng0/btq2hZeCxqo/s2U7YsngTaTgzi5T1UmBe0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5Lng0/btq2hZeCxqo/s2U7YsngTaTgzi5T1UmBe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5Lng0%2Fbtq2hZeCxqo%2Fs2U7YsngTaTgzi5T1UmBe0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;immeditate format Instructions이다.&lt;br&gt;4개의 영역으로 구성되어 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Operation code&lt;/li&gt;
&lt;li&gt;source register&lt;/li&gt;
&lt;li&gt;target register&lt;/li&gt;
&lt;li&gt;constant 또는 address&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;해당 format에 들어가는 명령어의 종류는 Immediate arithmetic 와 load/store instructions 이다.&lt;br&gt;target register는 destination register 일 수도 있고 source register가 될수도 있다.&lt;br&gt;constant는 해당 범위까지 표현할 수 있다.&lt;br&gt;address는 source register에서 더해지는 offset이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design Principle 4: Good design demands good compromises&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;상이한 서로 다른 두개를 하나로 만드는 것이다.&lt;br&gt;Immediate arithmetic 와 load/store instructions은 각각 다른 instruction이지만&lt;br&gt;I-format Instructions으로 두개를 모두 사용할 수 있다.&lt;br&gt;이렇게 되면 Instruction의 복잡도가 낮아진다.&lt;br&gt;format이 단순해져서 훨씬 더 고성능을 얻을 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;9. Stored Program Computers&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ezJT2s/btq2hDpm88K/EqBJFVfq3ntD2bzIE9Z4MK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ezJT2s/btq2hDpm88K/EqBJFVfq3ntD2bzIE9Z4MK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ezJT2s/btq2hDpm88K/EqBJFVfq3ntD2bzIE9Z4MK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FezJT2s%2Fbtq2hDpm88K%2FEqBJFVfq3ntD2bzIE9Z4MK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;메모리에는 다양한 프로그램이 들어가며 명령어는 binary로 되어있다.&lt;br&gt;인스터럭션과 데이터는 메모리에 있다.&lt;br&gt;프로그램은 프로그램에 관련된 프로그램을 제공한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;어떤 바이너리 코드가 다른 머신에서 실행될 수 있는지는 표준화된 ISA가 지원이 되면 가능하다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;10. Logical Operations&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVINNv/btq2gXojW7d/DvuoL7NOF66AFr7RnXJJyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVINNv/btq2gXojW7d/DvuoL7NOF66AFr7RnXJJyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVINNv/btq2gXojW7d/DvuoL7NOF66AFr7RnXJJyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVINNv%2Fbtq2gXojW7d%2FDvuoL7NOF66AFr7RnXJJyk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;이런 bit연산은 한 word에서 특정한 bit의 값을 뽑아내거나 추가할 때 효과적으로 사용할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;11. Shift Operations&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bApWvG/btq2ieilhEb/QyZLpeah3txpKwuYdCww9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bApWvG/btq2ieilhEb/QyZLpeah3txpKwuYdCww9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bApWvG/btq2ieilhEb/QyZLpeah3txpKwuYdCww9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbApWvG%2Fbtq2ieilhEb%2FQyZLpeah3txpKwuYdCww9K%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;R-format Instructions이다.&lt;br&gt;shamt는 shift를 몇번 할 것인지를 나타낸다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Shift left logical은 bit를 왼쪽으로 shift하고 0으로 채우는 것이다,&lt;br&gt;i만큼 bit를 shift left를 하게 되면 2에 i로 제곱한 효과가 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Shift right logical bit를 오른쪽으로 shift하고 0을 채우는 것이다.&lt;br&gt;i만큼 bit를 shift right를 하게 되면 2에 i로 나머지 연산을 한 효과가 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;12. AND Operations&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GutRp/btq2kCweQep/OekBdBhiYr5DZ4gDD6o3lK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GutRp/btq2kCweQep/OekBdBhiYr5DZ4gDD6o3lK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GutRp/btq2kCweQep/OekBdBhiYr5DZ4gDD6o3lK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGutRp%2Fbtq2kCweQep%2FOekBdBhiYr5DZ4gDD6o3lK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;특정한 bit의 값을 뽑아낼때 사용한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;13. OR Operations&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crS4yz/btq2kBD55UW/jg3kV54uTNWR4sQAfVSZrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crS4yz/btq2kBD55UW/jg3kV54uTNWR4sQAfVSZrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crS4yz/btq2kBD55UW/jg3kV54uTNWR4sQAfVSZrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrS4yz%2Fbtq2kBD55UW%2Fjg3kV54uTNWR4sQAfVSZrk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;특정한 bit를 1로 설정할때 사용하기 좋다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;14. NOT Operations&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSEzWg/btq2iVph0HR/xzfXVSAFe4eNwjMu2tvo9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSEzWg/btq2iVph0HR/xzfXVSAFe4eNwjMu2tvo9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSEzWg/btq2iVph0HR/xzfXVSAFe4eNwjMu2tvo9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSEzWg%2Fbtq2iVph0HR%2FxzfXVSAFe4eNwjMu2tvo9k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;bit를 모두 반전시키는 것이다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;MIPS는 NOT Operations를 가지고 있지 않다.&lt;br&gt;대신 nor Operations을 사용하여 NOT Operations을 구현한다.(nor $t0, $t1, $zero)&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;15. Conditional Operations&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VUgNE/btq2hKaXEYu/mhFNzmfbajDWbFRe0M13g0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VUgNE/btq2hKaXEYu/mhFNzmfbajDWbFRe0M13g0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VUgNE/btq2hKaXEYu/mhFNzmfbajDWbFRe0M13g0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVUgNE%2Fbtq2hKaXEYu%2FmhFNzmfbajDWbFRe0M13g0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;C언어로 보면 조건문과 같다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;beq rs, rt, L1은 rs와 rt의 값이 같으면 L1으로 가는 것이고 같지 않으면 다음 명령어를 실행한다.&lt;br&gt;bne rs, rt, L1은 rs와 rt의 값이 같지 않으면 L1으로 가는 것이다. 같으면 다음 명령어를 실행한다.&lt;br&gt;j L1은 무조건 L1으로 가는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;15-1. Compiling If Statements&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Es2hG/btq2hq4QydW/023cNWJwpqy8kkpifGdow0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Es2hG/btq2hq4QydW/023cNWJwpqy8kkpifGdow0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Es2hG/btq2hq4QydW/023cNWJwpqy8kkpifGdow0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEs2hG%2Fbtq2hq4QydW%2F023cNWJwpqy8kkpifGdow0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;f, g, h, i, j가 $s0, $s1, $s2, $s3일때 컴파일 된 MIPS 코드를 봐보자&lt;br&gt;&lt;br/&gt;&lt;br&gt;bne $s3, $s4, Else i와 j가 같으면 다음 명령어(add $s0, $s1, $s2)를 실행하고&lt;br&gt;그렇지 않다면 Else(sub $s0, $s1, $s2)를 실행한다.&lt;br&gt;만약 값이 같다고 했을 때 g와 h를 더한 후 f에 값을 집어 놓고 Exit을 실행하게 된다.&lt;br&gt;만약 값이 같지 않을 경우 g와 h를 뺀 후 다음 명령어인 Exit을 실행하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;15-2. Compiling Loop Statements&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kxem8/btq2iDIXGG3/IkCSS4PWNQwN5LRovlLws1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kxem8/btq2iDIXGG3/IkCSS4PWNQwN5LRovlLws1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kxem8/btq2iDIXGG3/IkCSS4PWNQwN5LRovlLws1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkxem8%2Fbtq2iDIXGG3%2FIkCSS4PWNQwN5LRovlLws1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;while문에 대한 C코드를 MIPS로 컴파일 한 경우이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;i를 2만큼 bit를 왼쪽으로 shift를 시킨 후 t1에 넣는다.(i가 1이라면 4가 된것), 즉 4를 곱한 것이다.&lt;br&gt;save가 integer 배열이라 1개의 element가 4byte이다.&lt;br&gt;그래서 index만큼 index에 4를 곱해준 다음 더해줘야 한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;t1과 save 배열의 시작주소를 더해서 다시 t1에 넣는다.&lt;br&gt;그 다음 t1을 4byte(word)만큼 load해서 t0에 넣는다.&lt;br&gt;그리고 t0와 $s5(k)가 같지 않으면 Exit으로 가고 같다면 다음 명령어를 실행한다.&lt;br&gt;$s3(i)에 1을 더한 후 $s3(i)에 넣는다.&lt;br&gt;그리고 Loop로 다시 점프한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;16. Basic Blocks&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/S1ePp/btq2hD3YGf7/707M6dssOqPqa0tvkvPZl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/S1ePp/btq2hD3YGf7/707M6dssOqPqa0tvkvPZl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/S1ePp/btq2hD3YGf7/707M6dssOqPqa0tvkvPZl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FS1ePp%2Fbtq2hD3YGf7%2F707M6dssOqPqa0tvkvPZl0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;명령어들의 시퀀스이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Basic Blocks은 2가지 조건을 만족해야 한다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;중간에 branch 명령어가 없어야 한다.&lt;/li&gt;
&lt;li&gt;중간에 branch target이 없어야 한다.(처음에는 있어도 된다.) - ex.(라벨되어 있는것 loop exit 등등)&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;br&gt;compiler는 Basic Blocks을 찾아서 Basic Blocks을 빨리 실행하도록 하는 일을 한다.&lt;br&gt;프로세서 역시 Basic Blocks을 빨리 실행하게 한다.&lt;br&gt;compiler와 프로세서는 Basic Blocks을 높은 성능을 얻기 위해 최대한 빨리 실행해야한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;17. More Conditional Operations&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AJ3UF/btq2hsPan5z/lJnbFN1pkO2bh95Kyi53r0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AJ3UF/btq2hsPan5z/lJnbFN1pkO2bh95Kyi53r0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AJ3UF/btq2hsPan5z/lJnbFN1pkO2bh95Kyi53r0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAJ3UF%2Fbtq2hsPan5z%2FlJnbFN1pkO2bh95Kyi53r0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;어떤 조건이 true이면 결과에 1을 세팅하고 그렇지 않으면 0을 세팅한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;slt rd, rs, rt&lt;br&gt;rs가 rt보다 작으면 rd에 1을 저장하는 것이고 그렇지 않다면 0을 저장하는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;slti rt, rs, constant&lt;br&gt;rs가 상수보다 작으면 rt는 1 아니면 0을 저장하는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;slt는 beq, bne와 같이 사용된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;18. Branch Instruction Design&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGntWy/btq2lCis5dy/UDI6kBtnMHsplfgyGBEer0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGntWy/btq2lCis5dy/UDI6kBtnMHsplfgyGBEer0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGntWy/btq2lCis5dy/UDI6kBtnMHsplfgyGBEer0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGntWy%2Fbtq2lCis5dy%2FUDI6kBtnMHsplfgyGBEer0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;blt, bge, etc 이런것은 왜 지원해주지 않는가&lt;br&gt;&lt;br/&gt;&lt;br&gt;H/W에서 어떤 값이 같은지 틀린지보다는 작거나 크거나 연산이 훨씬 복잡하다.&lt;br&gt;=, ≠을 연산하는 것보다 &amp;lt;, ≥을 연산하는 것이 더 오래 걸린다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;즉, 더 많은 시간이 필요하므로 더 느린 clock period를 사용해야 한다.&lt;br&gt;느린 clock period를 사용하면 모든 연산은 다 느려지게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;그래서 beq, bne이 흔하게 사용되어 이것만 지원해주게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;19. Signed vs. Unsigned&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MgYlO/btq2hfCkrau/6W4ON2qIXcyaZkD0tIgdUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MgYlO/btq2hfCkrau/6W4ON2qIXcyaZkD0tIgdUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MgYlO/btq2hfCkrau/6W4ON2qIXcyaZkD0tIgdUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMgYlO%2Fbtq2hfCkrau%2F6W4ON2qIXcyaZkD0tIgdUK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Unsigned 는 명령어 끝에 u를 붙여야줘야 한다.(sltu, sltui)&lt;/p&gt;</description>
      <category>Computer Science/컴퓨터 구조</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/17</guid>
      <comments>https://immigrationssu.tistory.com/entry/6-Instructions-Language-of-the-Computer-2#entry17comment</comments>
      <pubDate>Sat, 10 Apr 2021 22:34:54 +0900</pubDate>
    </item>
    <item>
      <title>5.  Instructions: Language of the Computer 1</title>
      <link>https://immigrationssu.tistory.com/entry/5-Instructions-Language-of-the-Computer</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 최규상 교수님 컴퓨터구조 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;참고 : 컴퓨터 구조 및 설계 - David A. Patterson,John L. Hennessy&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=bae6f412d7ecafe8&quot;&gt;http://www.kocw.net/home/cview.do?lid=bae6f412d7ecafe8&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. Instruction Set&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mhzvO/btq2bIxdgWk/o7cjDO9uYsJvCalejakpkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mhzvO/btq2bIxdgWk/o7cjDO9uYsJvCalejakpkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mhzvO/btq2bIxdgWk/o7cjDO9uYsJvCalejakpkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmhzvO%2Fbtq2bIxdgWk%2Fo7cjDO9uYsJvCalejakpkK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Instruction Set은 컴퓨터에서 사용되는 instruction의 집합이다.&lt;br&gt;다른 컴퓨터들은 각기 다른 Instruction Set을 가지게 된다.&lt;br&gt;하지만 대부분의 경우 공통된 특성을 가지고 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;초창기 컴퓨터들은 매우 단순한 Instruction Set을 가지고 있었으며 Instruction Set의 종류가 적었다.&lt;br&gt;최근 CPU들 또한 단순한 Instruction Set을 가지게 된다.&lt;br&gt;물론 초창기와 최근 사이에 complex instruction set을 가지는 CPU들이 존재했었다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;단순 - 복잡 - 단순의 과정을 거친 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;1-1. Instruction Set Architecture(ISA)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAiRm/btq2b1i1nQE/qnZ8OUAKSk3DQyNAIks711/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAiRm/btq2b1i1nQE/qnZ8OUAKSk3DQyNAIks711/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAiRm/btq2b1i1nQE/qnZ8OUAKSk3DQyNAIks711/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAiRm%2Fbtq2b1i1nQE%2FqnZ8OUAKSk3DQyNAIks711%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;ISA는 H/W와 가장 낮은 레벨의 S/W(ex.시스템 소프트웨어or 운영체제임)간에 인터페이스이다.&lt;br&gt;이런 ISA를 사용하여 필요한 정보들을 machine에 주는 것이다.&lt;br&gt;즉 필요한 정보를 Instruction에 담아서 H/W(CPU)에 주면 H/W는 그 Instruction을 실행한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;ISA를 사용하면 똑같은 소프트웨어를 실행할 때 성능과 비용에 따라 다른 implementation이 가능하게 된다.&lt;br&gt;즉, ISA만 같다면 같은 소프트웨어를 여러개의 CPU에서 실행할 수 있다는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;1-2. Application binary interface(ABI)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIg74a/btq17Zme8S8/WWeF8gQxEAfJVN7DYroC2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIg74a/btq17Zme8S8/WWeF8gQxEAfJVN7DYroC2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIg74a/btq17Zme8S8/WWeF8gQxEAfJVN7DYroC2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIg74a%2Fbtq17Zme8S8%2FWWeF8gQxEAfJVN7DYroC2k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;ABI는 ISA와 O/S의 combination을 칭한다.&lt;br&gt;ABI는 유저관점에서 아주 중요하다.&lt;br&gt;ABI가 같다는 것은 어떤 프로그램이 특정 PC에서 실행될 때 그 프로그램은&lt;br&gt;다른 컴퓨터에서 ABI가 같으면 해당 컴퓨터에서도 실행할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;예를 들어 집에서 PC를 사용할 때 MS Word를 사용한다고 하면 , 다른 환경에서도 MS Word를 실행할 수 있다.&lt;br&gt;그 이유는 두개의 컴퓨터 ABI가 같기 때문이다.&lt;br&gt;같은 운영체제(윈도우)와 같은 CPU(인텔)를 사용하기 때문이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. The MIPS Instruction Set&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0iJ1d/btq16yJpR9H/MO8o7ryE2vXcAQMP8G8Bm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0iJ1d/btq16yJpR9H/MO8o7ryE2vXcAQMP8G8Bm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0iJ1d/btq16yJpR9H/MO8o7ryE2vXcAQMP8G8Bm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0iJ1d%2Fbtq16yJpR9H%2FMO8o7ryE2vXcAQMP8G8Bm0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;MIPS(Million Instructions Per Second)는 컴퓨터의 연산 속도를 나타내는 단위로도 쓰이지만 CPU의 이름이기도 하다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;MIPS는 RISC(축소 명령 집합 컴퓨터)의 구조 및 그 구조를 이용한 MCU를 뜻한다.&lt;br&gt;임베디드 시스템에서 많이 쓰이고 있으며 최근엔 ARM이 많이 쓰이고 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;MIPS에서 사용하는 대부분의 특성은 많은 CPU들에 의해서 공유되고 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-1. Arithmetic Operations(산술연산)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6ND61/btq2aMzVX74/tL2kUhK52izMgQ3IPKKTOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6ND61/btq2aMzVX74/tL2kUhK52izMgQ3IPKKTOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6ND61/btq2aMzVX74/tL2kUhK52izMgQ3IPKKTOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6ND61%2Fbtq2aMzVX74%2FtL2kUhK52izMgQ3IPKKTOk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;컴퓨터에서 많이 사용되는 Operations 중 하나인 Arithmetic Operations이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;어셈블리 언어에서 add a, b, c를 하게 되면 b, c를 더해 a에 할당하게 된다.&lt;br&gt;모든 Arithmetic Operations은 이와 같은 형태를 갖게 됨&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design Principle 1: Simplicity favours regularity&lt;/strong&gt;&lt;br&gt;CPU를 설계하는 첫번째 원칙이다.&lt;br&gt;규칙성을 주게 되면 구현할 때 수월하다.&lt;br&gt;간단하게 만들어야 낮은가격으로 높은 성능을 낼 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EngHZ/btq17an0ybl/eLIainqbdcGHbKWrlydGx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EngHZ/btq17an0ybl/eLIainqbdcGHbKWrlydGx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EngHZ/btq17an0ybl/eLIainqbdcGHbKWrlydGx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEngHZ%2Fbtq17an0ybl%2FeLIainqbdcGHbKWrlydGx1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;C코드를 MIPS 코드로 컴파일하면 위와 같이 된다.&lt;br&gt;위 코드에서는 쉽게 이해할 수 있게 변수로 표현되어 있지만 실제로는 레지스터에서 수행되어야 한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-2. Register Operands&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbXs0H/btq16yCDMEE/EIdx6J1UY66JvQxK5RLRNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbXs0H/btq16yCDMEE/EIdx6J1UY66JvQxK5RLRNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbXs0H/btq16yCDMEE/EIdx6J1UY66JvQxK5RLRNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbXs0H%2Fbtq16yCDMEE%2FEIdx6J1UY66JvQxK5RLRNk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Arithmetic Operations은 Register를 사용하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;MIPS는 32bit Register를 32개 가지고 있다.&lt;br&gt;32bit data를 &amp;#39;word&amp;#39;라고 칭한다.&lt;br&gt;자주 사용되는 데이터를 Register에 로딩해서 사용하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;어셈블리에서는 temporary 값을 사용하는 $t Register와&lt;br&gt;variables 저장하기 위한 $s Register를 사용하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design Principle 2: Smaller is faster&lt;/strong&gt;&lt;br&gt;CPU를 설계하는 두번째 원칙이다.&lt;br&gt;작을 수록 빠르다는 뜻이다.&lt;br&gt;대부분의 경우에 해당된다.&lt;br&gt;메모리의 크기도 작을 수록 빠르다.&lt;br&gt;Register가 메인 메모리에 비해 훨씬 빠르다.(약 1000배)&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsRQNo/btq18pSu9DF/vu7LepUXJpIkV1U4KWkLi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsRQNo/btq18pSu9DF/vu7LepUXJpIkV1U4KWkLi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsRQNo/btq18pSu9DF/vu7LepUXJpIkV1U4KWkLi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsRQNo%2Fbtq18pSu9DF%2Fvu7LepUXJpIkV1U4KWkLi1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;위 예제 C 코드에서 g는 s1, h는 s2, i는 s3, j는 s4에 맵핑 되어있다.&lt;br&gt;MIPS 코드로 컴파일된 코드를 보게 되면 $s1과 $s2를 더해 $t0에 넣고&lt;br&gt;$s3와 $s4를 더해 $t1에 넣게 된다.&lt;br&gt;이후 $t0와 $t1을 뺀 다음 $s0에 넣게되며 s0는 f에 맵핑되어 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-3. byte addresses&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ng3lw/btq2c4fhjrd/8CF86aulVyH9mKBZTiYjR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ng3lw/btq2c4fhjrd/8CF86aulVyH9mKBZTiYjR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ng3lw/btq2c4fhjrd/8CF86aulVyH9mKBZTiYjR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fng3lw%2Fbtq2c4fhjrd%2F8CF86aulVyH9mKBZTiYjR1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;대부분의 컴퓨터에서는 메모리를 byte단위로 지정할 수 있게 된다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alignment restriction(정렬제약)&lt;br&gt;  대부분의 32bit 프로세서 같은 경우에는 memory address는 word단위로 맞춰진다,&lt;br&gt;  기본 엑세스단위가 32bit이기 때문이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Endian은 데이터를 word에 어떤 방식으로 저장할 것이냐를 뜻한다.&lt;br&gt;Big endian은 leftmost byte로 큰 단위가 앞에 나온다.&lt;br&gt;Little endian은 rightmost byte로 작은 단위가 앞에 나온다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;대부분의 CPU는 1개의 endian만 지원함&lt;br&gt;최근 나온 ARM 프로세서는 2개 중 1개를 설정하여 사용할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-4. Memory Operands&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwWut3/btq16RWgJNp/OIkgoPZLgE61wkVb3pf0dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwWut3/btq16RWgJNp/OIkgoPZLgE61wkVb3pf0dk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwWut3/btq16RWgJNp/OIkgoPZLgE61wkVb3pf0dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwWut3%2Fbtq16RWgJNp%2FOIkgoPZLgE61wkVb3pf0dk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;메인 메모리는 데이터를 저장하는 공간으로 사용된다.&lt;br&gt;Arithmetic Operations에서 이런 데이터를 사용할 경우 메모리에서 레지스터로 데이터를 로딩해야하고&lt;br&gt;연산의 결과를 레지스터에서 메모리로 써야한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;그러나 메모리는 byte단위로 엑세스한다.&lt;br&gt;따라서 각각의 메모리 address는 byte로 되어있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;또한 word 단위로 정렬되어 있어 address는 4의 배수로 되어 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;즉, MIPS는 byte단위로 엑세스되며 word단위로 정렬되고 Big endian을 사용한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h3&gt;2-4-1. Memory Operand Example 1&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeL6l3/btq2b4NFAc2/Yc7fBkKvESbsIsoKuuJwi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeL6l3/btq2b4NFAc2/Yc7fBkKvESbsIsoKuuJwi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeL6l3/btq2b4NFAc2/Yc7fBkKvESbsIsoKuuJwi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeL6l3%2Fbtq2b4NFAc2%2FYc7fBkKvESbsIsoKuuJwi1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;해당 예제 C코드에서 g는 s1, h는 s2, A 배열은 s3부터 연속으로 맵핑되어 있다고 가정한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxRGHC/btq2dHRGZ3m/GeKNLkJDerXGbYFTZXdeGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxRGHC/btq2dHRGZ3m/GeKNLkJDerXGbYFTZXdeGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxRGHC/btq2dHRGZ3m/GeKNLkJDerXGbYFTZXdeGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxRGHC%2Fbtq2dHRGZ3m%2FGeKNLkJDerXGbYFTZXdeGk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;MIPS 컴파일 코드는 위와 같이 되어있다.&lt;br&gt;A배열에는 8개의 index가 있게 된다.&lt;br&gt;A[8]의 값을 가져오려면 A[0]로 부터 32byte 뒤에 있는 값을 가져오면 된다.&lt;br&gt;1개의 배열은 4byte다.&lt;br&gt;A의 배열은 8개의 index가 있다.&lt;br&gt;따라서 8개의 index에 4byte씩 곱하게 되면 32byte가 된다.&lt;br&gt;s3는 A배열의 시작주소이며 s3에 32를 더해야 한다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;load word는 메모리로 부터 데이터를 로딩하는 것이다.&lt;br&gt;메모리 주소가 필요하며 메모리 주소는 32(s3)으로 표현 된다.&lt;br&gt;이 값에 32를 더한 메모리 주소에 가서 1word(4byte)만큼 읽어 t0에 넣는 것이다.&lt;br&gt;t0에는 A[8]의 값이 들어가게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h3&gt;2-4-2. memory operands ex2&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t4bja/btq17a9qMiL/NoGy1BU3b5wf4MzWkcIfK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t4bja/btq17a9qMiL/NoGy1BU3b5wf4MzWkcIfK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t4bja/btq17a9qMiL/NoGy1BU3b5wf4MzWkcIfK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft4bja%2Fbtq17a9qMiL%2FNoGy1BU3b5wf4MzWkcIfK1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;해당 예제 C코드에서 h는 s2, A배열은 s3부터 연속으로 맵핑되어 있다고 가정한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baIRjW/btq2bHrA0wJ/rLqcLt36CI8kFkHygtbW9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baIRjW/btq2bHrA0wJ/rLqcLt36CI8kFkHygtbW9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baIRjW/btq2bHrA0wJ/rLqcLt36CI8kFkHygtbW9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaIRjW%2Fbtq2bHrA0wJ%2FrLqcLt36CI8kFkHygtbW9K%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;MIPS 컴파일 코드는 위와 같이 되어있다.&lt;br&gt;t0에 A[8]의 데이터를 로딩해온 후 값을 넣어준다.&lt;br&gt;그다음 s2와 t0를 더해 다시 t0에 넣는다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;store word는 t0에 있는 값을 해당 시작 주소(48($s3))에 저장하는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-5. Registers vs. Memory&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwoBsf/btq2aOxN9qN/pzLWBP8QZwxGLvZktDeux0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwoBsf/btq2aOxN9qN/pzLWBP8QZwxGLvZktDeux0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwoBsf/btq2aOxN9qN/pzLWBP8QZwxGLvZktDeux0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwoBsf%2Fbtq2aOxN9qN%2FpzLWBP8QZwxGLvZktDeux0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Registers는 메모리보다 엑세스시간이 훨씬 빠르다.&lt;br&gt;MIPS 프로세서에서는 메모리 데이터를 Registers에 로딩을 해서&lt;br&gt;연산을 한 후 메모리에 저장하는 방식을 택한다.(load store architecture)&lt;br&gt;&lt;br/&gt;&lt;br&gt;MIPS는 명령어가 직접적으로 메모리에 엑세스해서 메모리에 있는 데이터를 연산을 하지 못하고&lt;br&gt;항상 load라는 명령을 사용해서 메모리에서 데이터를 Registers에 올린 후 연산을 한 다음&lt;br&gt;다시 메모리에 저장하는 방식을 택하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;위와 같은 방식을 사용하면 load staore때문에 많은 명령어가 필요하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;컴파일러는 Registers를 잘사용해야 한다.&lt;br&gt;variables을 위한 Registers를 효율적으로 잘 사용하는 것이 매우 중요하다.&lt;br&gt;잘 활용할 수록 메모리를 엑세스하는 횟수가 줄어들게 된다.&lt;br&gt;Registers optimization(최적화)은 컴파일러, 컴퓨터 구조에서 매우 중요하다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-6 MIPS Register File&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E5z0f/btq17GGZN7t/rDDhpnQuUM1OGgyKCleW3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E5z0f/btq17GGZN7t/rDDhpnQuUM1OGgyKCleW3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E5z0f/btq17GGZN7t/rDDhpnQuUM1OGgyKCleW3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE5z0f%2Fbtq17GGZN7t%2FrDDhpnQuUM1OGgyKCleW3k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;MIPS는 32개의 32bit 레지스터를 가지고 있으며&lt;br&gt;2개의 read포트와 1개의 write포트를 가지게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cysj4n/btq2dJaUAun/rrVL6fGqugJZwxswQzxb1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cysj4n/btq2dJaUAun/rrVL6fGqugJZwxswQzxb1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cysj4n/btq2dJaUAun/rrVL6fGqugJZwxswQzxb1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcysj4n%2Fbtq2dJaUAun%2FrrVL6fGqugJZwxswQzxb1K%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Register는 메모리보다 빠르다.&lt;br&gt;Register를 사용하면 컴파일러가 훨씬 수월하며 코드의 접적도가 높다.&lt;br&gt;메모리를 엑세스할 때 32bit필요하지만 레지스터는 5bit이 필요하기 때문이다.&lt;br&gt;즉, 코드의 길이가 짧아진다.&lt;br&gt;코드의 집적도가 높다면 똑같은 일을 할 때 코드가 적다는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-7. MIPS Register Convention&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5g80J/btq2clhli7H/2fpxa0zDKT7gSaa9U7uG31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5g80J/btq2clhli7H/2fpxa0zDKT7gSaa9U7uG31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5g80J/btq2clhli7H/2fpxa0zDKT7gSaa9U7uG31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5g80J%2Fbtq2clhli7H%2F2fpxa0zDKT7gSaa9U7uG31%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;$zero는 하드웨어로 정해져있으며 항상 0을 가지고 Read만 가능하다.&lt;br&gt;$at은 어셈블러만 사용하도록 예약되어있다.&lt;br&gt;$a는 function call을 사용하는 araguments로 사용된다.&lt;br&gt;$v는 returned values를 쓰는데 사용된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-8. Immediate Operands&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xzb0P/btq16QiMl6r/KSkZX0iBCxPR8QbzKur3ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xzb0P/btq16QiMl6r/KSkZX0iBCxPR8QbzKur3ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xzb0P/btq16QiMl6r/KSkZX0iBCxPR8QbzKur3ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXzb0P%2Fbtq16QiMl6r%2FKSkZX0iBCxPR8QbzKur3ak%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;산술연산에서 기존 add의 피연산자는 모두 Register였다.&lt;br&gt;그러나 immediate operands는 3개의 피연산자 중 1개가 상수값을 갖는 것이다.&lt;br&gt;상수 값에서 음수는 add에서 가능하지만 sub에서는 지원하지 않는다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design principle 3: Make the common case fast&lt;/strong&gt;&lt;br&gt;CPU를 설계하는 세번째 원칙이다.&lt;br&gt;많이 발생되는 사항을 빨리 처리해야 한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;프로그램을 하다 보면 아주 적은 값의 상수를 많이 사용한다.&lt;br&gt;immediate operands를 지원하면 상수값을 바로 사용할 수 있지만&lt;br&gt;immediate operands이 지원되지 않는다면 메모리에서 항상 로드해야 한다.&lt;br&gt;immediate operands는 load 인스트럭션을 줄여주며 Make the common case fast의 대표적인 예이다.&lt;/p&gt;
&lt;h3&gt;2-8-1. The Constant Zero&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgM5vA/btq2dBjGPFS/EhU3XZkiJ0FmWEcjLoogB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgM5vA/btq2dBjGPFS/EhU3XZkiJ0FmWEcjLoogB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgM5vA/btq2dBjGPFS/EhU3XZkiJ0FmWEcjLoogB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgM5vA%2Fbtq2dBjGPFS%2FEhU3XZkiJ0FmWEcjLoogB1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;MIPS의 0번 Resister이다.&lt;br&gt;Read만 가능한 Resister로 항상 0을 갖게 된다.&lt;br&gt;Move Instruction을 구현할 때 사용 된다.(복사할 때)&lt;/p&gt;</description>
      <category>Computer Science/컴퓨터 구조</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/16</guid>
      <comments>https://immigrationssu.tistory.com/entry/5-Instructions-Language-of-the-Computer#entry16comment</comments>
      <pubDate>Thu, 8 Apr 2021 22:32:46 +0900</pubDate>
    </item>
    <item>
      <title>4. Computer Avstractions and Technology 4</title>
      <link>https://immigrationssu.tistory.com/entry/4-Computer-Avstractions-and-Technology-4</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 최규상 교수님 컴퓨터구조 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;참고 : 컴퓨터 구조 및 설계 - David A. Patterson,John L. Hennessy&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=0342b09d1a791dd8&quot;&gt;http://www.kocw.net/home/cview.do?lid=0342b09d1a791dd8&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. Power Trends&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VoUhn/btq1Mqwstvp/3KmWmfdwh5XNgw3f0F0VV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VoUhn/btq1Mqwstvp/3KmWmfdwh5XNgw3f0F0VV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VoUhn/btq1Mqwstvp/3KmWmfdwh5XNgw3f0F0VV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVoUhn%2Fbtq1Mqwstvp%2F3KmWmfdwh5XNgw3f0F0VV1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;wall은 파워와 메모리에서 사용하는 표현이다.&lt;br&gt;이 부분은 Powerwall에 대한 내용이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;그래프롤 보게되면 2004년까지 clock rate는 급격히 증가하였으나 2004년 이후로는 정체되어 있다.&lt;br&gt;clock rate이 증가하면서 전력소모 또한 급격히 증가하게 되었다. 그러나 2004년 이후로 전력소모는 감소하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;이기간 동안 Power는 30배 증가하였고 전압은 5V에서 1V로 줄어들었으며 Frequency는 1000배 빨라졌다.&lt;br&gt;Frequency가 1000배 빨리진 것에 반해 전력소모는 30배밖에 증가하지 않았다.&lt;br&gt;왜냐하면 전압을 1v로 낮췄기 때문이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;clock rate가 더 이상 증가하지 않은 이유는 전력 소모 때문이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. reducing power&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcTBu8/btq1ISnSdJN/74I5SL0rJOWSlSDtM995p0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcTBu8/btq1ISnSdJN/74I5SL0rJOWSlSDtM995p0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcTBu8/btq1ISnSdJN/74I5SL0rJOWSlSDtM995p0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcTBu8%2Fbtq1ISnSdJN%2F74I5SL0rJOWSlSDtM995p0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;요즘 컴퓨터는 전력소모를 위해 많은 노력을 한다.&lt;br&gt;새로운 CPU를 설계한다고 할때 기존에 CPU보다 capacitive load를 85퍼센트 사용하고&lt;br&gt;전압과 Frequency를 15% 감소할 경우&lt;br&gt;공식을 이용해 계산하면 기존의 CPU보다 약 52퍼센트의 전력소모를 사용한다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Powerwall&lt;br&gt;  더 이상 전압을 1V이하로 낮추지 못함&lt;br&gt;  전력을 더 이상 낮추지 못하기 때문에 발열을 줄이지 못함&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;clock rate을 향상시키지 못한 이유는 발열을 더이상 낮추지 못했기 때문이다.&lt;br&gt;그래서 나온 성능향상 방법이 Multi Core이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3.Uniprocessor Performance&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vuWlR/btq1KAM5y87/6FN0c3FmHPFwfKtOczuYN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vuWlR/btq1KAM5y87/6FN0c3FmHPFwfKtOczuYN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vuWlR/btq1KAM5y87/6FN0c3FmHPFwfKtOczuYN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvuWlR%2Fbtq1KAM5y87%2F6FN0c3FmHPFwfKtOczuYN0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;이 그래프는 싱글코어 프로세서의 퍼포먼스 그래프이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;2004년을 기점으로 멀티코어가 나오게 된다.&lt;br&gt;싱글코어에서는 매년 52퍼센트씩 성능이 향상되었지만&lt;br&gt;2004년을 기점으로 성능 향상이 매년 22퍼로 낮아지게 되었다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Power, instruction level parallelism(명령어 수준 병렬성), Memory latency와 같은 제약조건으로&lt;br&gt;성능향상에 제한이 생기게 되었다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;4.Multiprocessors&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xAaGo/btq1K32zFlO/KBSVHjRBQo6pDf0Z92tlM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xAaGo/btq1K32zFlO/KBSVHjRBQo6pDf0Z92tlM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xAaGo/btq1K32zFlO/KBSVHjRBQo6pDf0Z92tlM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxAaGo%2Fbtq1K32zFlO%2FKBSVHjRBQo6pDf0Z92tlM1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;2004년을 기점으로 싱글코어의 clock rate을 더 이상 증가시키지 못했기 때문에 CPU의 성능 향상을 못하게 되었다.&lt;br&gt;그래서 다른 방식으로 성능향상을 꾀하였다.&lt;br&gt;그것이 바로 1개의 칩안에 프로세서를 여러개 두게 되는 Multi-Core이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Multi-Core의 성능향상을 위해선 Parallel 프로그램을 사용해야 한다.&lt;br&gt;기존에 사용한 Siquential 프로그램을 사용하면 Multi-Core에서의 성능향상은 없게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;instruction level parallelism은 H/W가 알아서 명령어를 동시에 실행시켜주는 것이기 때문에&lt;br&gt;프로그래머는 이런 것을 고려할 필요가 없으며&lt;br&gt;CPU가 알아서 여러개의 명령을 동시에 실행시켜서 성능향상을 가져오게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;하지만 프로그래머가 Parallel 프로그램을 만들어야 한다.&lt;br&gt;1개의 일을 여러개로 나눴을 경우 여러개의 일이 비슷한 Load를 가져야 한다.&lt;br&gt;그리고 communication과 synchronization의 overhead를 줄여줘야 한다.&lt;br&gt;이것은 아주 어려운 작업이다.&lt;/p&gt;
&lt;p&gt;그래서 멀티코어에서의 성능향상은 기존 싱글코어보다 향상 폭이 낮아질 수 밖에 없어지는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;5. SPEC&lt;/h1&gt;
&lt;h2&gt;5-1. SPEC CPU Benchmark&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9c3yO/btq1MqwsIZ2/nZrpooCkHWMZdNv5patwP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9c3yO/btq1MqwsIZ2/nZrpooCkHWMZdNv5patwP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9c3yO/btq1MqwsIZ2/nZrpooCkHWMZdNv5patwP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9c3yO%2Fbtq1MqwsIZ2%2FnZrpooCkHWMZdNv5patwP1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;SPEC은 CPU, I/O, Web 등의 성능을 측정해주는 벤치마크를 만들어주는 회사이다.&lt;br&gt;그중 CPU에 관련된 벤치마크를 SPEC CPU Benchmark라고 한다.&lt;br&gt;이것을 통해 CPU 성능을 측정하게 된다.&lt;/p&gt;
&lt;h2&gt;5-2. CINT2006 for Intel Core i7 920&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfA7jC/btq1JVxt64n/YHkWozjvx1RWDkxMQSHwo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfA7jC/btq1JVxt64n/YHkWozjvx1RWDkxMQSHwo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfA7jC/btq1JVxt64n/YHkWozjvx1RWDkxMQSHwo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfA7jC%2Fbtq1JVxt64n%2FYHkWozjvx1RWDkxMQSHwo0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;인텔 i7 920의 SPEC 벤치마크이다.&lt;br&gt;해당 CPU의 geometric mean의 spec ratio는 25.7이다.&lt;br&gt;즉 reference machine에 비해 25.7배 빠르다는 뜻이다.&lt;br&gt;해당 값이 클수록 성능이 좋은 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;5-3. SPEC Power Benchmark&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSYmgu/btq1K3aqNcI/BCWv1BEcSFozp0HEkwi6SK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSYmgu/btq1K3aqNcI/BCWv1BEcSFozp0HEkwi6SK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSYmgu/btq1K3aqNcI/BCWv1BEcSFozp0HEkwi6SK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSYmgu%2Fbtq1K3aqNcI%2FBCWv1BEcSFozp0HEkwi6SK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;SPEC은 전력소모에 관련한 벤치마크 또한 만들었다.&lt;br&gt;Power 벤치마크의 단위는 ssj_ops per watt이다&lt;br&gt;Watt당 Server Side Java의 오퍼레이션의 수이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;5-4. SPECpower_ssj2008 for Xeon X5650&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUzYVm/btq1KB6jqYs/jfeDZnOUcAT7tdYJyLH2Vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUzYVm/btq1KB6jqYs/jfeDZnOUcAT7tdYJyLH2Vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUzYVm/btq1KB6jqYs/jfeDZnOUcAT7tdYJyLH2Vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUzYVm%2Fbtq1KB6jqYs%2FjfeDZnOUcAT7tdYJyLH2Vk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;인텔의  Xeon X5650  Power를 측정한 것이다.&lt;br&gt;해당 SPEC 벤치마크 결과는 2490이 되게 된다.&lt;br&gt;따라서 해당 값이 클수록 Watt당 많은 오퍼레이션을 수행한 것으로 전력효율이 좋은 것을 나타낸다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;6. Pitfall: Amdahl’s Law&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CsEZD/btq1JWwiUdV/Oa90mzRPJULuEMtJphvK31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CsEZD/btq1JWwiUdV/Oa90mzRPJULuEMtJphvK31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CsEZD/btq1JWwiUdV/Oa90mzRPJULuEMtJphvK31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCsEZD%2Fbtq1JWwiUdV%2FOa90mzRPJULuEMtJphvK31%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;컴퓨터의 어느 한 부분을 성능향상 시키면 전체 퍼포먼스의 성능향상은 그것에 비례하게 된다.&lt;br&gt;시스템의 한 Component의 성능을 향상하면 전체 시스템의 성능 향상은&lt;br&gt;그 Component가 시스템의 얼마나 비중을 차지하는지에 따라 비례해서 전체시스템의 성능이 향상되는 것이다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;예를 들어 곱하기 연산은 전체연산이 100초일 경우 80초를 차지하게 된다.&lt;br&gt;이럴 경우 곱셈 연산 성능을 향상시켜 전체 성능을 5배 향상시키려면 곱셈 연산을 얼마나 향상시켜야 하는가?&lt;br&gt;공식에 대입하여 보면 n은 무한대로 향해야만 성능향상이 된다. 즉, 해당 질문은 불가능 하다는 얘기다.&lt;br&gt;곱셈 연산의 성능 향상만으로는 전체 성능을 5배 향상시키는 것은 불가능하다는 것이다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;corollary : 어떤 시스템의 성능향상을 하고자 하면 그 시스템에서 가장많은 비중을 차지하는 컴포넌트를 빠르게 만드는 것이그 시스템의 많은 성능향상을 가져오게 되는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;7. Fallacy: Low Power at Idle&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/srL28/btq1K3IfqoN/E4KVvcdxJ08eEdi5QiiOJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/srL28/btq1K3IfqoN/E4KVvcdxJ08eEdi5QiiOJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/srL28/btq1K3IfqoN/E4KVvcdxJ08eEdi5QiiOJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsrL28%2Fbtq1K3IfqoN%2FE4KVvcdxJ08eEdi5QiiOJ0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;idle일때의 전력소모에 관련한 것이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;위에 나온 i7에 벤치마크를 보게되면&lt;br&gt;100%사용할 때는 258W, 50% 사용할 때는 170W를 사용하게 된다.&lt;br&gt;그러나 10%만 사용해도 121W를 사용하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;CPU는 10%만큼 사용하지 않아도 전력소모는 47%만큼 사용하게 되는 것이다.&lt;br&gt;CPU LOAD와 전력소모는 비례하지 않는다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;구글의 데이터센터를 예를 들었을 때&lt;br&gt;데이터 센터는 10~50% load만큼 사용하게 된다.&lt;br&gt;100%를 사용하는 것은 전체 사용시간에 1%도 되지 않는다.&lt;br&gt;그러나 load가 낮더라도 전력소모는 아주 많다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;따라서 프로세서를 만들때는 load에 비례되도록 전력소모를 만드는 것이 필요하게 된다.&lt;br&gt;그래서 이부분은 컴퓨터 아키텍트들의 큰 숙제이다.&lt;/p&gt;
&lt;h1&gt;8. Pitfall: MIPS as a Performance Metric&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf4Snu/btq1OMFMkSY/qK0XYgoUCaqCLZH25OlfP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf4Snu/btq1OMFMkSY/qK0XYgoUCaqCLZH25OlfP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf4Snu/btq1OMFMkSY/qK0XYgoUCaqCLZH25OlfP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf4Snu%2Fbtq1OMFMkSY%2FqK0XYgoUCaqCLZH25OlfP1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;MIPS는 시간당 몇 백만개의 instruction을 실행하는 가를 나타내는 것이다.&lt;br&gt;MIPS를 성능의 단위로 쓴적이 있다.&lt;br&gt;그러나 MIPS는 많은 오해를 가져올 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;이유는 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컴퓨터 마다 ISA가 다름&lt;/li&gt;
&lt;li&gt;명령어 마다 필요한 CPI 값이 모두 다를 수 있음&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MIPS 는 CPI에 의해 좌우된다.&lt;br&gt;하지만 CPI는 CPU와 프로그램에 의해 달라질 수 있게 된다.&lt;br&gt;그래서 정확한 성능측정단위가 되기 어렵게 되는 것이다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;SPEC CPU 벤치마크 프로그램을 사용하는 것이 더 정확하다고 볼 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;9. Concluding Remarks&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFgs4O/btq1ONLr2LU/hRC1JeCJkyXbcYMHi2gsVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFgs4O/btq1ONLr2LU/hRC1JeCJkyXbcYMHi2gsVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFgs4O/btq1ONLr2LU/hRC1JeCJkyXbcYMHi2gsVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFgs4O%2Fbtq1ONLr2LU%2FhRC1JeCJkyXbcYMHi2gsVK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Computer Science/컴퓨터 구조</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/15</guid>
      <comments>https://immigrationssu.tistory.com/entry/4-Computer-Avstractions-and-Technology-4#entry15comment</comments>
      <pubDate>Sat, 3 Apr 2021 22:57:33 +0900</pubDate>
    </item>
    <item>
      <title>3. Computer Avstractions and Technology 3</title>
      <link>https://immigrationssu.tistory.com/entry/3-Computer-Avstractions-and-Technology-3</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 최규상 교수님 컴퓨터구조 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;참고 : 컴퓨터 구조 및 설계 - David A. Patterson,John L. Hennessy&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=8cc704c8dfcaf55b&quot;&gt;http://www.kocw.net/home/cview.do?lid=8cc704c8dfcaf55b&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. CPU Time&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;348&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5LHUm/btq1s4hSQTz/PRyXaCa3c8rVsYYrkKnkg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5LHUm/btq1s4hSQTz/PRyXaCa3c8rVsYYrkKnkg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5LHUm/btq1s4hSQTz/PRyXaCa3c8rVsYYrkKnkg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5LHUm%2Fbtq1s4hSQTz%2FPRyXaCa3c8rVsYYrkKnkg0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;348&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;CPU Time은 CPU에서 걸린 Cycle의 수와 하나의 Clock Cycle Time의 곱으로 표현할 수 있다.&lt;br&gt;이것을 통해 알 수 있는 것은 성능은 Clock Cycle의 수를 줄이면 향상이 된다는 것이다.&lt;br&gt;마찬가지로 Clock Rate를 증가시키면 CPU Time은 감소하게 되며 성능은 향상이 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;컴퓨터 아키텍트는 Clock Rate와 Clock Cycle에 민감할 수 밖에 없다.&lt;br&gt;Cycle의 수를 감소시키면 Clock Rate가 감소하거 반대로 Clock Rate를 증가시키면 Cycle의 수도 늘어날 수 있기 때문이다.&lt;br&gt;컴퓨터 아키텍트는 이 두가지를 잘 조절하여 성능을 향상시켜야 한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;1-2. CPU Time Example&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q0tkM/btq1z32sF1b/tvkSek5bwWtlTdr44PMTiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q0tkM/btq1z32sF1b/tvkSek5bwWtlTdr44PMTiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q0tkM/btq1z32sF1b/tvkSek5bwWtlTdr44PMTiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq0tkM%2Fbtq1z32sF1b%2FtvkSek5bwWtlTdr44PMTiK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;컴퓨터A는 2GHz Clock을 가지며 10초의 CPU Time을 가진다.&lt;br&gt;컴퓨터B를 설계할 때 컴퓨터A에서의 CPU Time 10초를 6초로 줄이려 한다.&lt;br&gt;그리고 1.2배 빠른 Clock Cycle을 사용하려 한다.&lt;br&gt;이런 경우의 컴퓨터B의 Clock Rate는 몇이여야 하는가?&lt;br&gt;&lt;br/&gt;&lt;br&gt;위 공식을 따라 계산을 하게 되면 Clock Rate는 4GHz가 필요하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. Instruction count and CPI&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLGgkd/btq1yEh4XRr/qaHdgsPKJAredBtl2X5n9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLGgkd/btq1yEh4XRr/qaHdgsPKJAredBtl2X5n9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLGgkd/btq1yEh4XRr/qaHdgsPKJAredBtl2X5n9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLGgkd%2Fbtq1yEh4XRr%2FqaHdgsPKJAredBtl2X5n9k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Clock Cycle은 Instruction의 수와 Instruction당 Cycle의 수(CPI) 곱으로 결정이 된다.&lt;br&gt;CPU Time은 Instruction과 CPI와 Clock Cycle Time 곱으로 결정이 된다.&lt;br&gt;또한 Instruction과 CPI의 곱을 Clcock Rate로 나눈 값으로 결정이 될 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Instruction의 수는 프로그램, ISA, 컴파일러에 의해 결정이 된다.&lt;br&gt;CPI는 CPU H/W에 따라 결정이 된다.&lt;br&gt;또한 Instruction의 종류가 다를 경우 각각의 다른 Instruction은 서로 다른 CPI를 요구한다.&lt;br&gt;Instruction이 혼합되어 있는 경우에는 Average CPI를 사용해야 한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-1. CPI Example&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dXb8cn/btq1tDqVVsr/5KvGXOzhG4R9M8uKKqrMp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dXb8cn/btq1tDqVVsr/5KvGXOzhG4R9M8uKKqrMp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dXb8cn/btq1tDqVVsr/5KvGXOzhG4R9M8uKKqrMp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXb8cn%2Fbtq1tDqVVsr%2F5KvGXOzhG4R9M8uKKqrMp1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;컴퓨터 A의 Cycle Time이 250ps 일때(4GHz Clock Rate) CPI는 2.0이다.&lt;br&gt;컴퓨터 B의 Cycle Time이 500ps 일때(2GHz Clock Rate) CPI는 1.2이다.&lt;br&gt;이 두 컴퓨터는 같은 ISA를 사용한다.(Instruction의 수가 동일함)&lt;br&gt;&lt;br/&gt;&lt;br&gt;이 경우 두개의 컴퓨터중 어느것이 더 빠른가?&lt;br&gt;공식에 따라 계산을 해보면 컴퓨터A가 컴퓨터B보다 CPU time이 1.2배 빠르다는 것을 알 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-2. CPI in More Detail&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHU9KU/btq1yEI7et0/XWDFQzKcLkmMu5pse1t3T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHU9KU/btq1yEI7et0/XWDFQzKcLkmMu5pse1t3T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHU9KU/btq1yEI7et0/XWDFQzKcLkmMu5pse1t3T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHU9KU%2Fbtq1yEI7et0%2FXWDFQzKcLkmMu5pse1t3T0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;다른 Instruction Class들은 다른 Cycle의 수를 요구하게 된다.&lt;br&gt;여러 개의 Instruction Class를 사용할 경우에는 Average CPI를 사용해야 한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2-3. CPI Example 2&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjxlH8/btq1vimimhw/vGnWKTy74RuH3QJKoPsVJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjxlH8/btq1vimimhw/vGnWKTy74RuH3QJKoPsVJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjxlH8/btq1vimimhw/vGnWKTy74RuH3QJKoPsVJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjxlH8%2Fbtq1vimimhw%2FvGnWKTy74RuH3QJKoPsVJ0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;sequence1과 sequence2라는 2가지의 컴파일 코드가 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;sequence1의 Instruction의 수는 5개이며 sequence2의 Instruction의 수는 6개로&lt;br&gt;sequence2가 sequence1보다 Instruction이 1개 더 많게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;Clock Cycle은 각 Class의 수와 CPI를 곱하면 된다.&lt;br&gt;sequence1의 Clock Cycle은 10, sequence2의 Clock Cycle은 9가 된다.&lt;br&gt;Average CPI는 전체 Clock Cycle를 Instruction의 수로 나눠주면 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;sequence1의 Average CPI는 2.0, sequence2의 Average CPI는 1.5가 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;sequence2의 Instruction의 수는 sequence1보다 1개가 더 많았지만 실제로 걸린 Clock Cycle의 수는 1만큼 덜 걸리게 된다.&lt;br&gt;따라서 sequence2가 sequence1보다 더 빨리 실행될 수 있게 된다.&lt;br&gt;1개의 Instruction을 실행할 때 걸리는 CPI가 sequence1보다 짧기 때문이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3. Performance Summary&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CmdLj/btq1ByHIhPn/DKosw7yPksod0fWozRkQc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CmdLj/btq1ByHIhPn/DKosw7yPksod0fWozRkQc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CmdLj/btq1ByHIhPn/DKosw7yPksod0fWozRkQc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCmdLj%2Fbtq1ByHIhPn%2FDKosw7yPksod0fWozRkQc1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;CPU Time을 보게 되면 Program은 Instruction으로 구성되어 있고 Instruction은 Clock Cycle로 구성되어있고&lt;br&gt;Clock Cycle은 Seconds로 구성되어 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;이것을 보고 알 수 있는 것은 아래와 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Algorithm은 Instruction의 수에 영향을 주고 , CPI는 영향을 줄 수도 있다.  &lt;/li&gt;
&lt;li&gt;프로그램 언어는 Instruction의 수와 CPI 모두에게 영향을 준다.  &lt;/li&gt;
&lt;li&gt;컴파일러 또한 마찬가지로 Instruction의 수와 CPI 모두에게 영향을 준다.&lt;/li&gt;
&lt;li&gt;ISA는 Instruction의 수와 CPI, Clock Cycle Time에 영향을 준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;3-1. Example&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J2DJ5/btq1AFmMLAk/drtTDK65oI57WNEsEpyyW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J2DJ5/btq1AFmMLAk/drtTDK65oI57WNEsEpyyW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J2DJ5/btq1AFmMLAk/drtTDK65oI57WNEsEpyyW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ2DJ5%2Fbtq1AFmMLAk%2FdrtTDK65oI57WNEsEpyyW0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Instruction의 종류는 총 4가지가 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ALU&lt;/li&gt;
&lt;li&gt;Load&lt;/li&gt;
&lt;li&gt;Store&lt;/li&gt;
&lt;li&gt;Branch&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;br&gt;각 명령의 Freq는 각각 50, 20, 10, 20이며 CPI는 1, 5, 3, 2이다.&lt;br&gt;이럴 경우 Freq와 CPI를 곱하면 각각 0.5, 1.0, 0.3, 0.4가 된며 총합은 2.2이다.&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Data Cache를 사용해서 Average load time을 2 cycles로 줄였을 때 기존에 비해서 CPU Time이 얼마나 향상되는가&lt;br&gt; Average loat time을 2 Cycles로 줄이면 Load는 0.4가 되며 총합은 1.6이 된다.&lt;br&gt; 기존에 비해 37.5%만큼 향상이 되는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Branch prediction을 사용해서 Branch Time을 1 Cycle 만큼 줄였을 때 CPU Time이 얼마나 향상되는가&lt;br&gt; Branch Time을 1 Cycle만큼 줄이게 되면 Branch의 Freq는 10%가 되며 CPI와 곱한 값은 0.2가 된다.&lt;br&gt; 총합은 2.0으로 바뀌게 된다.&lt;br&gt; 기존에 비해 10%만큼 향상이 되는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;2개의 ALU를 한꺼번에 실행할 경우 CPU Time이 얼마나 향상되는가&lt;br&gt; 기존에 ALU의 CPI가 1이였는데 ALU 2개를 동시에 실행하면 CPI는 0.5가 된다.&lt;br&gt; 그러므로 계산을 하게되면 총합은 1.95가 되며&lt;br&gt; 기존에 비해 12.8% 향상이 되는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>Computer Science/컴퓨터 구조</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/14</guid>
      <comments>https://immigrationssu.tistory.com/entry/3-Computer-Avstractions-and-Technology-3#entry14comment</comments>
      <pubDate>Wed, 31 Mar 2021 23:23:20 +0900</pubDate>
    </item>
    <item>
      <title>2. Computer Avstractions and Technology 2</title>
      <link>https://immigrationssu.tistory.com/entry/2-Computer-Avstractions-and-Technology-2</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 최규상 교수님 컴퓨터구조 강의 정리&lt;br /&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br /&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br /&gt;&lt;br /&gt;참고 : 컴퓨터 구조 및 설계 - David A. Patterson,John L. Hennessy&lt;br /&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=83030621fe62e08e&quot;&gt;http://www.kocw.net/home/cview.do?lid=83030621fe62e08e&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. Components of a Computer&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;530&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwM8bA/btq1b9w14YW/PIWoXyurs2BzOsgTX7YvtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwM8bA/btq1b9w14YW/PIWoXyurs2BzOsgTX7YvtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwM8bA/btq1b9w14YW/PIWoXyurs2BzOsgTX7YvtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwM8bA%2Fbtq1b9w14YW%2FPIWoXyurs2BzOsgTX7YvtK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;530&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;많은 컴퓨터(데스크탑, 서버, 임베디드)에서 기본적으로 같은 구성요소를 가지고 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User-interface Device&lt;br /&gt;디스플레이, 키보드 마우스 등등&lt;/li&gt;
&lt;li&gt;Storage Devcies&lt;br /&gt;HDD, CD/DVD 등등&lt;/li&gt;
&lt;li&gt;Network&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;511&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1ovvG/btq1jlDht84/pDAEosEmK74nEUeXg7yHJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1ovvG/btq1jlDht84/pDAEosEmK74nEUeXg7yHJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1ovvG/btq1jlDht84/pDAEosEmK74nEUeXg7yHJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1ovvG%2Fbtq1jlDht84%2FpDAEosEmK74nEUeXg7yHJ1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;511&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;스마트폰 혹은 태블릿PC에서는 터치스크린도 사용되고 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;493&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8T4br/btq1pzfTBsm/uSe8qIvwjER4nBbMXPKOKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8T4br/btq1pzfTBsm/uSe8qIvwjER4nBbMXPKOKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8T4br/btq1pzfTBsm/uSe8qIvwjER4nBbMXPKOKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8T4br%2Fbtq1pzfTBsm%2FuSe8qIvwjER4nBbMXPKOKk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;493&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;LCD 스크린에서는 프레임 버퍼에 데이터를 쓰게 되면 화면에 해당 데이터들이 표시되게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;2. Inside the Processor(CPU)&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;349&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tCIc6/btq1owcDIky/1btFwnDGKTSEycAUHEfpY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tCIc6/btq1owcDIky/1btFwnDGKTSEycAUHEfpY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tCIc6/btq1owcDIky/1btFwnDGKTSEycAUHEfpY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtCIc6%2Fbtq1owcDIky%2F1btFwnDGKTSEycAUHEfpY0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;349&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;CPU는 3가지 구성요소가 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Datapath : 연산들을 수행하기 위한 여러 유닛들의 구조&lt;br /&gt;데이터가 어떤 operations을 해서 쭉 흘러가는지. 데이터가 어떻게 연산이 되는지&lt;/li&gt;
&lt;li&gt;Control : 명령어를 해석하고 레지스터와 ALU 사이의 명령 흐름을 제어한다.&lt;br /&gt;프로세스의 다양한 컴포넌트를 컨트롤 하게 된다.&lt;/li&gt;
&lt;li&gt;캐시메모리 - 속도가 빠른 장치와 느린 장치 사이에서 속도 차에 따른 병목 현상을 줄이기 위한 범용 메모리를 말한다.&lt;br /&gt;CPU 안에 아주 작고 빠른 SRAM을 가지고 있다&lt;br /&gt;이런 SRAM으로 구성된 캐시메모리에 자주 사용되는 데이터를 올려놓아 빠르게 엑세스하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;558&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FlAhq/btq1jlpF6mW/8cU53uuJhFA1kAwxeCDCy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FlAhq/btq1jlpF6mW/8cU53uuJhFA1kAwxeCDCy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FlAhq/btq1jlpF6mW/8cU53uuJhFA1kAwxeCDCy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFlAhq%2Fbtq1jlpF6mW%2F8cU53uuJhFA1kAwxeCDCy0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;558&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;애플의 A5 CPU이다.&lt;br /&gt;데이타패스가 4개가 있으며&lt;br /&gt;ARM 코어가 있다. 코어는 연산을 하는 곳이다.&lt;br /&gt;하단에는 SRAM에 대한 인터페이스도 있있으며&lt;br /&gt;I/O 인터페이스, USB 인터페이스 또한 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;3. Abstractions&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;531&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvEyY8/btq1nIYHgm4/bjXbeC32GVhYxOUUN5aGhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvEyY8/btq1nIYHgm4/bjXbeC32GVhYxOUUN5aGhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvEyY8/btq1nIYHgm4/bjXbeC32GVhYxOUUN5aGhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvEyY8%2Fbtq1nIYHgm4%2FbjXbeC32GVhYxOUUN5aGhk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;531&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;아주 복잡한 문제를 풀 때 추상화 기법이 효과적이다.(단순화)&lt;br /&gt;컴퓨터 구조에서는 ISA가 있다.&lt;br /&gt;ISA는 명령어 집합 구조이다.&lt;br /&gt;H/W S/W 인터페이스이며&lt;br /&gt;S/W는 Instruction으로 구성되어 있고 H/W는 Instruction을 실행한다.&lt;br /&gt;Instruction을 통해 데이터를 주고 받게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ABI는 단순히 말하면 ISA와 시스템 소프트웨어의 인터페이스이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Implementation은 ISA를 실제로 어떻게 구현할 것인지에 대한 내용을 말한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;4. A Safe Place for Data, Networks&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;549&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exupoo/btq1haIHBWS/KorSaWXXeJUzEdVYS0kd01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exupoo/btq1haIHBWS/KorSaWXXeJUzEdVYS0kd01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exupoo/btq1haIHBWS/KorSaWXXeJUzEdVYS0kd01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fexupoo%2Fbtq1haIHBWS%2FKorSaWXXeJUzEdVYS0kd01%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;549&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;DRAM은 휘발성이다.&lt;br /&gt;휘발성은 전원이 나가면 데이터들이 사라지게 된다.&lt;br /&gt;저장장치는 비휘발성이다.(HDD, 플래시메모리, SSD)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;543&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fv7No/btq1hahF9PY/D8YBeFxRi0ea38dpLYciLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fv7No/btq1hahF9PY/D8YBeFxRi0ea38dpLYciLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fv7No/btq1hahF9PY/D8YBeFxRi0ea38dpLYciLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFv7No%2Fbtq1hahF9PY%2FD8YBeFxRi0ea38dpLYciLK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;543&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;네트워크는 LAN, WAN, WIFI, 블루투스 등이 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;5. Technology Trends&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;765&quot; data-origin-height=&quot;535&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3PYEG/btq1dzCfHK4/rmcfefUpTKHejXNsXcKXR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3PYEG/btq1dzCfHK4/rmcfefUpTKHejXNsXcKXR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3PYEG/btq1dzCfHK4/rmcfefUpTKHejXNsXcKXR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3PYEG%2Fbtq1dzCfHK4%2FrmcfefUpTKHejXNsXcKXR0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;765&quot; data-origin-height=&quot;535&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;무어의 법칙과 관련이 있다.&lt;br /&gt;X축은 시간(연도), Y축은 성능을 뜻한다.&lt;br /&gt;시간에 따라 성능은 급격히 증가하게 된다.&lt;br /&gt;예전에 비해서 DRAM을 아주 싼가격에 대량으로 사용할 수 있게 되었다.&lt;br /&gt;표와 같이 시간이 지남에 따라 아주 급격히 성능이 향상되게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;6. Semiconductor Technology&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;341&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7OsqY/btq1e7lclos/fZxHN5KOsMQmU4jaeZq380/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7OsqY/btq1e7lclos/fZxHN5KOsMQmU4jaeZq380/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7OsqY/btq1e7lclos/fZxHN5KOsMQmU4jaeZq380/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7OsqY%2Fbtq1e7lclos%2FfZxHN5KOsMQmU4jaeZq380%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;341&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;실제 칩을 만든다는 것은 실리콘에 기판을 새겨 넣는 것을 말한다.&lt;br /&gt;Conductors, Insulators, Switch를 동작이 되도록 하는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;512&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lig8s/btq1nHldM4C/OmW7CaAsy3WKLCj0Muas1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lig8s/btq1nHldM4C/OmW7CaAsy3WKLCj0Muas1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lig8s/btq1nHldM4C/OmW7CaAsy3WKLCj0Muas1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flig8s%2Fbtq1nHldM4C%2FOmW7CaAsy3WKLCj0Muas1k%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;512&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;실리콘을 얇계 펴 Wafer를 만들고 가공단계를 거쳐 패턴을 입히게 된다.&lt;br /&gt;패턴을 테스트하고 패키지를 만든다.(실제 칩을 만드는 것)&lt;br /&gt;각각의 칩이 제대로 동작하는지를 체크하며 테스트가 완료되면 사용자에게 판매가 되는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Yield란 수율을 뜻하며 Wafer당 동작하는 die의 비율을 뜻한다.&lt;br /&gt;수율은 하나의 웨이퍼에서 칩이 몇개가 성공하는지 보는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;7. Performance&lt;/h1&gt;
&lt;h2&gt;7-1. Defining Performance&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;689&quot; data-origin-height=&quot;540&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwsGA8/btq1jma2q35/LHAzq9mO5vf6Fx8oCK1qe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwsGA8/btq1jma2q35/LHAzq9mO5vf6Fx8oCK1qe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwsGA8/btq1jma2q35/LHAzq9mO5vf6Fx8oCK1qe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwsGA8%2Fbtq1jma2q35%2FLHAzq9mO5vf6Fx8oCK1qe1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;689&quot; data-origin-height=&quot;540&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;비행기의 다양한 특성을 보여주는 그래프이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1번째 그래프(좌측 상단)는 한번에 태울수 있는 승객의 수를 나타내는 것이다.&lt;br /&gt;2번째 그래프(우측 상단)는 한번에 얼마나 멀리 날 수 있는지를 나타내는 것이다.&lt;br /&gt;3번째 그래프(좌측 하단)는 비행기의 속도를 나타내는 것이다.&lt;br /&gt;4번째 그래프(우측 하단)는 한번에 태울수 있는 승객의 수와 속도를 곱한 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이중에서 어떤 비행기가 가장 좋은 성능을 가지고 있다고 볼 수 있을까?&lt;br /&gt;성능의 기준을 승객수로 본다면 Boeing 747이 가장 좋고&lt;br /&gt;기준을 거리로 본다면 Douglas DC-8-50이 가장 좋고&lt;br /&gt;속력으로 본다면 BAC/Sud Concorde가 가장 좋다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;성능이란 어떻게 정의하느냐에 따라 달라지게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;7-2. Response Time and Throughput&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;502&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6ueJ6/btq1jkRTLC0/sMVBHQaAJS4kUPuwjn0HK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6ueJ6/btq1jkRTLC0/sMVBHQaAJS4kUPuwjn0HK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6ueJ6/btq1jkRTLC0/sMVBHQaAJS4kUPuwjn0HK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6ueJ6%2Fbtq1jkRTLC0%2FsMVBHQaAJS4kUPuwjn0HK0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;502&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;컴퓨터에서의 성능이란 무엇인가&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Response time : task를 수행하는데 어느정도의 시간이 걸리는지&lt;/li&gt;
&lt;li&gt;Throughput : 단위시간당 얼마나 많은 task를 수행할 수 있는지&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;다음 두가지 경우에 따라서 Response time과 Throughput은 어떠한 영향을 받는가&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;첫번째는 기존의 프로세서보다 더빠른 CPU를 사용할 경우 이다.&lt;br /&gt;당연히 Response time과 Throughput 모두 영향을 받는다.&lt;br /&gt;새로운 CPU를 사용하면 일을 더 빨리하게 된다.&lt;br /&gt;따라서 Response time은 줄어들고 Throughput은 높아지게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;두번째는 기존의 프로세서와 동일한 프로세서를 추가하는 것이다.&lt;br /&gt;Response time은 변하지 않으나 Throughput은 높아지게 된다.&lt;br /&gt;2개의 코어에서 각각 서로 다른일을 할 수 있기 때문에 단위시간당 하는일은 더 많아지게 되는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;일반적으로 Response time을 줄이면 Throughput은 같이 증가하게된다.&lt;br /&gt;Response time은 Throughput에 영향을 주지만&lt;br /&gt;Throughput은 Response time에 영향을 주지 않을 수 있다.&lt;/p&gt;
&lt;p&gt;성능은 주로 Response time으로 표현할 수 있게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;7-3. Relative Performance&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;528&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/neNHv/btq1pz1g7E2/NsxyJlgESYlrUH2BhPa5h0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/neNHv/btq1pz1g7E2/NsxyJlgESYlrUH2BhPa5h0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/neNHv/btq1pz1g7E2/NsxyJlgESYlrUH2BhPa5h0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FneNHv%2Fbtq1pz1g7E2%2FNsxyJlgESYlrUH2BhPa5h0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;528&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Response time은 execution time(실행 시간)이라 할 수 있다.&lt;br /&gt;execution time이 짧을수록 더 좋은 성능을 나타낸다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;'X는 Y보다 N배 빠르다'는 것은 execution time Y를 execution time X로 나눴을 때N이 나오면&lt;br /&gt;X가 Y보다 n배 빠르다라고 할수 있는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;성능과 execution time은 반비례관계이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A는 10초가 걸리고 B는 15초가 걸린 다고 할때&lt;br /&gt;이런 경우 execution time B / execution time A는 1.5가 된다.&lt;br /&gt;이런 경우 A는 B보다 1.5배 빠르다라고 표현할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;7-4. Measuring Execution Time&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;524&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5O73R/btq1e8dleM8/rdP2ZM7b1QN5Blz2SDErhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5O73R/btq1e8dleM8/rdP2ZM7b1QN5Blz2SDErhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5O73R/btq1e8dleM8/rdP2ZM7b1QN5Blz2SDErhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5O73R%2Fbtq1e8dleM8%2FrdP2ZM7b1QN5Blz2SDErhK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;524&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Elapsed time이란 Response time의 총합을 나타낸다.(오퍼레이션의 시작부터 끝까지 걸린 시간)&lt;br /&gt;CPU 걸린 시간과 I/O에서 걸린 시간, 운영체제에서 걸린 시간을 모두 포함한다.&lt;br /&gt;즉, 시스템 전체의 성능을 정의하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CPU time은 어떤 일을 처리할 때 CPU에서 걸린 시간을 나타낸다.&lt;br /&gt;I/O에서 걸린 시간과 CPU가 다른일을 할 때 시간을 제외하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CPU time은 user CPU time과 System CPU time으로 나뉘게 된다.&lt;br /&gt;user CPU time은 사용자가 사용할 때 시간을 나타내며&lt;br /&gt;System CPU time은 운영체제가 사용할 때 시간을 나타낸다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;프로그램들은 CPU 또는 시스템 성능에 의해 서로 다르게 영향을 받을 수 있다.&lt;br /&gt;어떤 프로그램은 CPU에 영향을 받을 수 있고 어떤것은 I/O의 영향을 받을 수 있는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;7-5. CPU Clocking&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;548&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CHtvy/btq1g939slv/MfC8R6wyLqtmTDFK2T5eGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CHtvy/btq1g939slv/MfC8R6wyLqtmTDFK2T5eGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CHtvy/btq1g939slv/MfC8R6wyLqtmTDFK2T5eGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCHtvy%2Fbtq1g939slv%2FMfC8R6wyLqtmTDFK2T5eGk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;548&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Rising Edge에서 다음 Rising Edge까지를 Clock period라고 하며 하나의 Clock Cycle이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;단위는 시간의 단위를 쓴다.&lt;br /&gt;Clock Frequency(rate)는 초당 몇 Clock Cycle이 존재하는지를 나타낸다.&lt;br /&gt;Hz 단위를 사용하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;7-6. Machine Clock Rate&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;325&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcGCiN/btq1pA0c0ii/eOqeKrKKXrqF7kus36oDc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcGCiN/btq1pA0c0ii/eOqeKrKKXrqF7kus36oDc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcGCiN/btq1pA0c0ii/eOqeKrKKXrqF7kus36oDc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcGCiN%2Fbtq1pA0c0ii%2FeOqeKrKKXrqF7kus36oDc1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;325&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Clock Frequency는 Clock period와 반비례 관계이다.&lt;br /&gt;Clock Cycle은 1/Clock Rate 이다.&lt;/p&gt;</description>
      <category>Computer Science/컴퓨터 구조</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/13</guid>
      <comments>https://immigrationssu.tistory.com/entry/2-Computer-Avstractions-and-Technology-2#entry13comment</comments>
      <pubDate>Mon, 29 Mar 2021 22:41:09 +0900</pubDate>
    </item>
    <item>
      <title>1.  Computer Avstractions and Technology 1</title>
      <link>https://immigrationssu.tistory.com/entry/1-Computer-Avstractions-and-Technology-1</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 최규상 교수님 컴퓨터구조 강의 정리&lt;br /&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br /&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br /&gt;&lt;br /&gt;참고 : 컴퓨터 구조 및 설계 - David A. Patterson,John L. Hennessy&lt;br /&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=c01867b2883af28c&quot;&gt;http://www.kocw.net/home/cview.do?lid=c01867b2883af28c&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. The Computer Revolution&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;434&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwN5NZ/btq1haAHVnV/ecX4CkveCerxWkpOcLGB8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwN5NZ/btq1haAHVnV/ecX4CkveCerxWkpOcLGB8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwN5NZ/btq1haAHVnV/ecX4CkveCerxWkpOcLGB8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwN5NZ%2Fbtq1haAHVnV%2FecX4CkveCerxWkpOcLGB8K%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;434&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;무어의 법칙에 의해서 컴퓨터기술은 급격하게 발전해왔다.&lt;br /&gt;그로 인해 다양한 새로운 어플리케이션들이 가능해지게 되었다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;316&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MLG5b/btq1dzHNygY/iDyKLYQ3DGENYD2zQPNYw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MLG5b/btq1dzHNygY/iDyKLYQ3DGENYD2zQPNYw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MLG5b/btq1dzHNygY/iDyKLYQ3DGENYD2zQPNYw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMLG5b%2Fbtq1dzHNygY%2FiDyKLYQ3DGENYD2zQPNYw0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;316&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;무어의 법칙은 1965년에 인텔 CEO인 Gordon Moore가 특정한 싱글 칩에 들어가는 트랜지스터의 수는&lt;br /&gt;매년 2배씩 늘어날 것을 예언한 내용이다.&lt;br /&gt;실제로는 2배보다 더 빠르게 증가하였다.&lt;br /&gt;이렇게 많은 트랜지스터가 집적이 가능하기 때문에 다양한 새로운 어플리케이션들을 실행할 수 있게 되었다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;2. Classes of Computers&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;379&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bn3zxv/btq1aRvDrKp/eGtsRn0mhikVSMJzbJpoq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bn3zxv/btq1aRvDrKp/eGtsRn0mhikVSMJzbJpoq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bn3zxv/btq1aRvDrKp/eGtsRn0mhikVSMJzbJpoq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbn3zxv%2Fbtq1aRvDrKp%2FeGtsRn0mhikVSMJzbJpoq0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;379&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;PC는 일반적인 용도로 사용되며 상당히 가격대 성능비에 민감하다.&lt;br /&gt;Server Computer는 많은 회사에서 자신들의 회사에서 중요한 데이터를 처리하는데 사용된다.&lt;br /&gt;보통 PC 보다는 고가, 대용량, 고성능이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;391&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsFNZa/btq090fxOEB/7XGPzReliuE21R0LLgqYnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsFNZa/btq090fxOEB/7XGPzReliuE21R0LLgqYnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsFNZa/btq090fxOEB/7XGPzReliuE21R0LLgqYnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsFNZa%2Fbtq090fxOEB%2F7XGPzReliuE21R0LLgqYnK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;391&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;아주 특수한 목적으로 복잡한 엔지니어링 문제를 푸는데 사용되는 슈퍼컴퓨터가 있다.&lt;br /&gt;아주 고가이며 전력소모도 많고 유지비용도 많이 들게 된다.&lt;br /&gt;우리나라에서는 기상청, 국방과학연구소등에서 운영하고 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;임베디드 컴퓨터는 큰 시스템에 컴퓨터가 하나의 요소로 구성되어있는 것을 뜻한다.&lt;br /&gt;아주 적은 전력소모를 가지며 가격 또한 저가이다.&lt;br /&gt;또한 유지비용이 적어 이에 해당되는 환경에서 대체로 많이 사용되게 된다.&lt;br /&gt;가장 대표적인 예로는 스마트폰, 태블릿PC등이 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;409&quot; data-origin-height=&quot;276&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IJMz1/btq1dAzVVQF/bP8drkWkAmrBeQDK5FPQG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IJMz1/btq1dAzVVQF/bP8drkWkAmrBeQDK5FPQG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IJMz1/btq1dAzVVQF/bP8drkWkAmrBeQDK5FPQG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIJMz1%2Fbtq1dAzVVQF%2FbP8drkWkAmrBeQDK5FPQG0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;409&quot; data-origin-height=&quot;276&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;컴퓨터에서 사용되는 기본적인 단위이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;3. The PostPC Era&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;440&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1Lmqa/btq1jmgBthO/8OIxXqxQ0BVVW1txftgQk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1Lmqa/btq1jmgBthO/8OIxXqxQ0BVVW1txftgQk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1Lmqa/btq1jmgBthO/8OIxXqxQ0BVVW1txftgQk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1Lmqa%2Fbtq1jmgBthO%2F8OIxXqxQ0BVVW1txftgQk1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;440&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;최근에 PC 트렌드이다.&lt;br /&gt;스마트폰과 태블릿 PC가 일반 PC보다 많이 팔리고 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;448&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BHWgj/btq1jkC4WA0/8RgY89wYK26qTzc4W0G6ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BHWgj/btq1jkC4WA0/8RgY89wYK26qTzc4W0G6ek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BHWgj/btq1jkC4WA0/8RgY89wYK26qTzc4W0G6ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBHWgj%2Fbtq1jkC4WA0%2F8RgY89wYK26qTzc4W0G6ek%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;448&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Post PC 시대에는 PMD와 같은 것들이 많이 사용되게 된다.&lt;br /&gt;보통 배터리로 동작하며 인터넷으로 연결되어 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cloud Computing은 특정한 데이터들을 처리해주는 하나의 서버에서 제공이 되는 것이다.&lt;br /&gt;서버팜에서 필요한 서버 만큼을 할당해서 받게 된다.&lt;br /&gt;필요한 소프트웨어를 서비스를 통해 제공받을 수 있다.&lt;br /&gt;내가 사용하는 소프트웨어의 일부분은 PMD에서 실행되며 중요한 부분은 클라우드에서 실행된다.&lt;br /&gt;즉, 복잡한 연산은 클라우드에서 실행되며 단순한 사용자 UI는 PMD에서 실행된다고 볼 수 있다.&lt;br /&gt;대표적으로 아마존과 구글에서 클라우드 컴퓨팅 서비스를 해준다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;436&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGEPIv/btq09y4GrRn/JDfdIQKKkWkkQ4rhGZemF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGEPIv/btq09y4GrRn/JDfdIQKKkWkkQ4rhGZemF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGEPIv/btq09y4GrRn/JDfdIQKKkWkkQ4rhGZemF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGEPIv%2Fbtq09y4GrRn%2FJDfdIQKKkWkkQ4rhGZemF0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;436&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;위와 같은 내용들을 해당 챕터에서 배우게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;4. Understanding Performance&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;389&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlLLM9/btq1asW8V9D/bEs43kfrL57b79LxGN2X50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlLLM9/btq1asW8V9D/bEs43kfrL57b79LxGN2X50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlLLM9/btq1asW8V9D/bEs43kfrL57b79LxGN2X50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlLLM9%2Fbtq1asW8V9D%2FbEs43kfrL57b79LxGN2X50%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;389&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;알고리즘&lt;br /&gt;Operation의 수로 정의가 된다.&lt;br /&gt;즉, 똑같은 2개의 알고리즘이 있을 경우 2개의 알고리즘 중 어떤것이 성능이 좋은가는 Operation의 수로 결정된다.&lt;br /&gt;Operation의 수가 작을 수록 성능이 좋은 것이다.&lt;/li&gt;
&lt;li&gt;프로그램 언어, 컴파일러, 아키텍쳐&lt;br /&gt;인스트럭션의 수로 결정이 된다.&lt;br /&gt;Operation은 좀 더 추상화된 개념이며 Instruction은 실제 CPU가 실행하는 명령어를 뜻한다.&lt;/li&gt;
&lt;li&gt;프로세서와 메모리 시스템&lt;br /&gt;얼마나 명령어를 빨리 실행할 것인지, 즉 단위시간당 얼마나 많은 명령어를 실행할 것인지로 결정이 된다.&lt;/li&gt;
&lt;li&gt;I/O 시스템&lt;br /&gt;I/O Operation의 수로 결정이 된다.&lt;br /&gt;즉, 단위시간당 얼마나 많은 I/O Operation을 실행한 것인지로 결정이 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;5. Eight Great Ideas&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;452&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnxAII/btq1g92SS2e/WqDKuiVslIodHRk5Mflkl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnxAII/btq1g92SS2e/WqDKuiVslIodHRk5Mflkl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnxAII/btq1g92SS2e/WqDKuiVslIodHRk5Mflkl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnxAII%2Fbtq1g92SS2e%2FWqDKuiVslIodHRk5Mflkl1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;452&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;컴퓨터 구조 분야에 대한 8가지 아이디어&lt;br /&gt;컴퓨터의 성능향상에 지대한 공헌을 함&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;무어의 법칙&lt;/li&gt;
&lt;li&gt;어떤 복잡한 문제를 단순화하기 위해 abstraction을 사용함&lt;/li&gt;
&lt;li&gt;아주 많이 사용되는 일반적인 것을 빠르게 하는 것이 성능향상에 도움이 됨&lt;/li&gt;
&lt;li&gt;Parallesim을 통해 Performance를 향상&lt;/li&gt;
&lt;li&gt;Pipelining을 통해 Performance를 향상&lt;/li&gt;
&lt;li&gt;예측을 통해 performance를 향상&lt;/li&gt;
&lt;li&gt;메모리 계층&lt;/li&gt;
&lt;li&gt;dependability via redundancy&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;6. Below Your Program&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;427&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/njvek/btq1aSnKUF4/peFRudLkXzkQWypvE7hpQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/njvek/btq1aSnKUF4/peFRudLkXzkQWypvE7hpQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/njvek/btq1aSnKUF4/peFRudLkXzkQWypvE7hpQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnjvek%2Fbtq1aSnKUF4%2FpeFRudLkXzkQWypvE7hpQk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;427&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Application software(프로그램들)&lt;br /&gt;일반적인 유저가 사용하는 소프트웨어이다.&lt;br /&gt;예를 들어 MS오피스, 웹브라우저 등등이 있다.&lt;/li&gt;
&lt;li&gt;System Software(윈도우 운영체제등등)&lt;br /&gt;운영체제, 컴파일러와 같이 컴퓨터가 실행되는데 아주 기본적인 소프트웨어를 의미한다.&lt;br /&gt;Compiler는 C/C++, JAVA와 같은 HLL로 작성된 code를 Machine code로 바꿔준다.&lt;br /&gt;운영체제는 기본적으로 어플리케이션이 사용되는 서비스를 제공해준다.&lt;br /&gt;I/O를 핸들링하거나 메모리, 스토리지를 관리해준다.&lt;br /&gt;사용자 어플리케이션 태스크를 스케쥴링해주며 자원을 공유하여 준다.&lt;/li&gt;
&lt;li&gt;Hardware(컴퓨터)&lt;br /&gt;실제 만질수 있는 피지컬한 것이다.&lt;br /&gt;프로세서, 메모리, I/O 컨트롤러등등&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;7. Levels of Program Code&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;639&quot; data-origin-height=&quot;442&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ma9TX/btq09xSavQJ/rmxmle6nnMnVZuCdv7PyKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ma9TX/btq09xSavQJ/rmxmle6nnMnVZuCdv7PyKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ma9TX/btq09xSavQJ/rmxmle6nnMnVZuCdv7PyKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMa9TX%2Fbtq09xSavQJ%2Frmxmle6nnMnVZuCdv7PyKk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;639&quot; data-origin-height=&quot;442&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High Level Language&lt;br /&gt;C언어, JAVA와 같은 것이다.&lt;br /&gt;컴파일러는 이러한 HLL을 Assembly language로 바꿔준다.&lt;/li&gt;
&lt;li&gt;Assembly language&lt;br /&gt;Machin instruction을 사람이 이해할 수 있도록 한 text적인 표현이다.&lt;br /&gt;컴파일러에 의해서 생성이 된다.&lt;br /&gt;이러한 Assembly language는 어셈블러를 통해 Machin code(binary)로 변환된다.&lt;/li&gt;
&lt;li&gt;Hardware representation&lt;br /&gt;binary digits로 연결되어 있다.&lt;br /&gt;instruction과 data를 binary로 표현하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Visaul Studio는 컴파일러와 어셈블러가 함께있는 것으로 보면된다.&lt;br /&gt;나눠서 컴파일러만 실행할 수 있으며 어셈블러만 실행할 수도 있다.&lt;/p&gt;
&lt;h2&gt;무어의 법칙&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;84&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFgeiG/btq1aQQ3EAG/3qHmBNmrGqkc5SP3Vsl7G1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFgeiG/btq1aQQ3EAG/3qHmBNmrGqkc5SP3Vsl7G1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFgeiG/btq1aQQ3EAG/3qHmBNmrGqkc5SP3Vsl7G1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFgeiG%2Fbtq1aQQ3EAG%2F3qHmBNmrGqkc5SP3Vsl7G1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;84&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;무어의 법칙이란 매 2년마다 하나의 칩에 들어가는 트랜지스터의 수가 2배가 된다는 것을 뜻한다.&lt;/p&gt;</description>
      <category>Computer Science/컴퓨터 구조</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/12</guid>
      <comments>https://immigrationssu.tistory.com/entry/1-Computer-Avstractions-and-Technology-1#entry12comment</comments>
      <pubDate>Sun, 28 Mar 2021 21:39:09 +0900</pubDate>
    </item>
    <item>
      <title>9. Process Synchronization 1</title>
      <link>https://immigrationssu.tistory.com/entry/11-Process-Synchronization-1</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;br /&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br /&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br /&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=aa53d6aa576466ee&quot;&gt;http://www.kocw.net/home/cview.do?lid=aa53d6aa576466ee&lt;/a&gt;, &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=5cf910642999f4a5&quot;&gt;http://www.kocw.net/home/cview.do?lid=5cf910642999f4a5&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. 데이터의 접근 - Race Condition&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;368&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lxIVK/btqWXak7NNM/vD7XzYYGqxrt3d9zK3urPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lxIVK/btqWXak7NNM/vD7XzYYGqxrt3d9zK3urPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lxIVK/btqWXak7NNM/vD7XzYYGqxrt3d9zK3urPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlxIVK%2FbtqWXak7NNM%2FvD7XzYYGqxrt3d9zK3urPk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;368&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;368&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Emdvg/btqWUruVbDm/NconohkPd0OHdRBLJ8JTwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Emdvg/btqWUruVbDm/NconohkPd0OHdRBLJ8JTwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Emdvg/btqWUruVbDm/NconohkPd0OHdRBLJ8JTwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEmdvg%2FbtqWUruVbDm%2FNconohkPd0OHdRBLJ8JTwK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;368&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;데이터를 Meomory에서 가져와 CPU에서 연산한 후 데이터의 결과를 Memory에 저장하게 된다.&lt;br /&gt;이떠 CPU가 1개일 경우에는 문제가 발생하지만 Memory는 1개인 상황에서 CPU가 여러개일 경우 문제가 발생하게 된다.&lt;br /&gt;이 문제를 &lt;b&gt;Race Condition&lt;/b&gt;이라 한다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Race Condition(경쟁 조건)&lt;/b&gt;은 둘 이상의 입력 또는 조작의 타이밍이나 순서 등이 결과 값에 영향을 줄 수 있는 상태를 뜻한다.&lt;/p&gt;
&lt;p&gt;Race Condition은 멀티프로세서 뿐만 아니라 공유 메모리를 사용하는 프로세스들 간에서도 자주 발생한다.&lt;br /&gt;또한 CPU가 1개이더라도 커널에서는 시스템 콜이 여러개가 오게될시 Race Condition이 발생하게 된다.&lt;/p&gt;
&lt;h1&gt;2. OS에서의 Race Condition&lt;/h1&gt;
&lt;p&gt;OS에서의 Race Condition이 발생하는 경우는 크게 3가지다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kernel 수행 중 Interrupt 발생 시&lt;/li&gt;
&lt;li&gt;Process가 System call을 하여 Kernel mode로 수행 중인데 context switch가 일어나는 경우&lt;/li&gt;
&lt;li&gt;Multiprocessor에서 Shared Memory 내의 kernel data&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2-1. Kernel 수행 중 Interruppt 발생 시&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;339&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cR2smJ/btqWU7W2nFj/YWBbPFexu01bQJIpKeI1a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cR2smJ/btqWU7W2nFj/YWBbPFexu01bQJIpKeI1a1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cR2smJ/btqWU7W2nFj/YWBbPFexu01bQJIpKeI1a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcR2smJ%2FbtqWU7W2nFj%2FYWBbPFexu01bQJIpKeI1a1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;339&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위 예시에서 Kernel에서 Count 변수 값을 증가시키고 Interrupt handler가 Count 변수를 감소시켜 Count값이 변화가 없어 보이지만 실제로는 Interrupt handler의 결과 값이 반영되지 않게 된다.&lt;br /&gt;왜냐하면 Kernel에서 이미 Interrupt handler가 들어오기 전에 Count 변수 값을 저장해놨다가 변수 값을 증가시키고 저장하기 때문이다.&lt;/p&gt;
&lt;p&gt;그래서 해당 문제에 대한 해결 방법으로는 &lt;b&gt;Kernel에서 특정 작업을 진행중일 때는 Interrpt를 disalbe 시킨 후 작업이 완료되면 Interrupt를 enalbe시켜주는 방법&lt;/b&gt;이 있다.&lt;/p&gt;
&lt;p&gt;결국에는 처리 순서를 정해주면 해결되는 문제이다.&lt;br /&gt;그러나 무작정 Interrupt를 막게 되면 CPU가 비효율적으로 돌아가는 일이 초래될 수 있다.&lt;/p&gt;
&lt;h3&gt;2-2. Process가 System call을 하여 Kernel mode로 수행 중인데 context switch가 일어나는 경우&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;282&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chhrv7/btqWTYT3AgZ/WBXckU5ebsbEFqNvfRgysK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chhrv7/btqWTYT3AgZ/WBXckU5ebsbEFqNvfRgysK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chhrv7/btqWTYT3AgZ/WBXckU5ebsbEFqNvfRgysK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fchhrv7%2FbtqWTYT3AgZ%2FWBXckU5ebsbEFqNvfRgysK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;282&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;368&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKgWJL/btqWX6iuQxj/Q0FRZ4XjnlvMtyFKU8Z0K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKgWJL/btqWX6iuQxj/Q0FRZ4XjnlvMtyFKU8Z0K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKgWJL/btqWX6iuQxj/Q0FRZ4XjnlvMtyFKU8Z0K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKgWJL%2FbtqWX6iuQxj%2FQ0FRZ4XjnlvMtyFKU8Z0K1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;368&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이번 예제 또한 2-1과 마찬가지로 '프로세스A'가 Count 변수를 이미 Load 했기 때문에 '프로세스B'에서 작업한 Count++은 반영되지 않고 '프로세스A'에서의 Count++ 작업만 저장이 된다.&lt;/p&gt;
&lt;p&gt;이러한 문제의 해결방법으로는 &lt;b&gt;프로세스가 커널 모드에 있을 때 CPU 할당 시간이 끝나도 CPU를 박탈당하지 않게 하는 것&lt;/b&gt;이다.&lt;br /&gt;이 방법을 사용할 시 CPU 할당시간이 제대로 지켜지지 않게될 수 있지만 RTOS가 아닌 시분할 동작이기 때문에 큰 문제가 발생하지는 않는다.&lt;/p&gt;
&lt;h3&gt;2-3. Multiprocessor에서 Shared Memory 내의 kernel data&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;312&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A8Yxe/btqWWsfif6U/FOYGeblNtQnxMQDgDO7ae0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A8Yxe/btqWWsfif6U/FOYGeblNtQnxMQDgDO7ae0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A8Yxe/btqWWsfif6U/FOYGeblNtQnxMQDgDO7ae0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA8Yxe%2FbtqWWsfif6U%2FFOYGeblNtQnxMQDgDO7ae0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;312&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이전 예제(2-1, 2-2)들은 CPU가 1개일 때 프로세스 혹은 커널이 뭔가를 작업하던 중 CPU 소유권이 넘어갔기 때문에 발생하는 문제이지만 이번 예제는 근본적으로 작업 주체인 CPU가 여럿일 경우에 발생하는 문제이다.&lt;/p&gt;
&lt;p&gt;이번 문제의 해결방법은 2가지가 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫번째, 커널 전체를 lock을 해준 후 작업이 완료되어 커널을 빠져나올 때 unlock을 해주는 것이다. 즉, 한번에 하나의 CPU만 커널에 들어갈 수 있게 하는 것이다.&lt;/li&gt;
&lt;li&gt;두번째, 커널 내부에 있는 각 공유데이터에 접근할 때마다 그 데이터에 대한 lock / unlock을 하는 방법이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;당연히 1번 방법은 커널 전체를 lock하는 것으로 매우 비효율적이다.&lt;/p&gt;
&lt;h1&gt;3. 프로세스 동기화(Process Synchronization)문제&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;310&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSHteV/btqWWsNrDvX/6QwgGuCscTXVSKWIJ8HaWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSHteV/btqWWsNrDvX/6QwgGuCscTXVSKWIJ8HaWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSHteV/btqWWsNrDvX/6QwgGuCscTXVSKWIJ8HaWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSHteV%2FbtqWWsNrDvX%2F6QwgGuCscTXVSKWIJ8HaWk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;310&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;공유 데이터(Shared data)의 동시 접근(Concurrent access)은 데이터의 불일치 문제(inconsistency)를 발생시킬 수 있다.&lt;/li&gt;
&lt;li&gt;일관성(Consistency) 유지를 위해서는 협력 프로세스(cooperating process)간의 실행 순서(orderly execution)를 정해주는 매커니즘이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Race Condition을 막기 위해서는 Concurrent process는 동기화(Synchronize)되어야 한다.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;4. Critical-Section Problem&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;359&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dXF7ey/btqWULUyHqA/gaqKqhDonOu6WlKwdTVrY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dXF7ey/btqWULUyHqA/gaqKqhDonOu6WlKwdTVrY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dXF7ey/btqWULUyHqA/gaqKqhDonOu6WlKwdTVrY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXF7ey%2FbtqWULUyHqA%2FgaqKqhDonOu6WlKwdTVrY0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;359&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;b&gt;Critical Section&lt;/b&gt;이란 공유 데이터를 접근하는 코드를 의미한다.&lt;br /&gt;만약 위 사진과 같이 P1에서 Critical Section이 실행 중일 때 CPU가 P2로 넘어가게 되면 P2의 Critical Section은 실행하지 않고 기다리고 있어야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;4-1. Initial Attempts to Solve Problem&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;322&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqzp0v/btqWULUyK8D/nHqRdtGDi8qkVRnvmGkGJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqzp0v/btqWULUyK8D/nHqRdtGDi8qkVRnvmGkGJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqzp0v/btqWULUyK8D/nHqRdtGDi8qkVRnvmGkGJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcqzp0v%2FbtqWULUyK8D%2FnHqRdtGDi8qkVRnvmGkGJk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;322&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;위 사진은 S/W로 코드를 넣어 Critical Section을 해결하는 방법이다.&lt;br /&gt;프로세스는 공유 데이터에 접근하는 코드(Critical Section)와 공유 데이터에 접근하지 않는 코드(remainder section)로 반복되어 구성될 것이다.&lt;br /&gt;공유 데이터를 접근하는 코드(Critical Section)이전에 entry section을 통해 일종의 lock을 걸어줄 것이며 exit section을 통해 unlock을 시켜줄 것이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;5. 프로그램적 해결법의 충족 조건&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;334&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2n8FP/btqWWszXm6Q/Y1dgE6vDXfVOszsYok2gzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2n8FP/btqWWszXm6Q/Y1dgE6vDXfVOszsYok2gzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2n8FP/btqWWszXm6Q/Y1dgE6vDXfVOszsYok2gzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2n8FP%2FbtqWWszXm6Q%2FY1dgE6vDXfVOszsYok2gzK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;334&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;프로그램적 해결법의 충족 조건은 3가지가 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mutual Exclusion - 배타적 접근&lt;/li&gt;
&lt;li&gt;Progress - 둘이 동시에 들어가는 것을 막고자 하다보니 Critical Section에 아무도 있지 않은 상태에서 들어가지 못하는 상황이 발생할 수 도 있다.&lt;/li&gt;
&lt;li&gt;Bounded Waition - Critical Section을 대기할 때 Starvation이 일어나지 않게 해야한다.만약 3개의 프로세스가 Critical Section을 사용하는데 2개의 프로세스만 서로 번갈아 가면서 사용하고 1개의 프로세스는 무한적으로 대기할 때 Bounded Waiting을 만족하지 못하는 상황이 발생하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;고급 언어의 문장들이 단일 Instruction이 아니기 떄문에 Critical Section 코드를 수행하는 도중에 CPU의 소유권을 빼앗겨서 발생하는 문제들이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;5-1. Algorithm 1&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;299&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crc8DC/btqW8GRaNg8/xaBMEIVcZm4JhFqdmaLTm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crc8DC/btqW8GRaNg8/xaBMEIVcZm4JhFqdmaLTm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crc8DC/btqW8GRaNg8/xaBMEIVcZm4JhFqdmaLTm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcrc8DC%2FbtqW8GRaNg8%2FxaBMEIVcZm4JhFqdmaLTm1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;299&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;turn 변수를 이용하여 프로세스의 순서를 정해준다.&lt;br /&gt;turn이 자기 차례일 때는 Critical Section안으로 들어가고 나올 때 turn의 변수 값을 바꿔준다.&lt;br /&gt;다른 프로세스는 turn이 자기 차례가 되지 않았을 때 While문이 돌아가고 있기 때문에 계속해서 대기를 하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;알고리즘 1은 충족 조건중 Mutual Exclusion은 만족하지만 Progress는 만족히자 못한다.&lt;br /&gt;알고리즘 1은 무조건 한 프로세스가 Critical Section에 들어갔다 나와야 하는 교대형식의 코드이다.&lt;br /&gt;프로세스들이 Critical Section에 들어가려는 빈도가 빈번하지 않을 수 있다.&lt;br /&gt;만약 프로세스A는 Critical Section에 빈번하게 접근을 해야하는데 프로세스B는 그렇지 않다고 한다면 프로세스A는 Critical Section에 접근하지 못하는 상황이 발생하게 된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;5-2. Algorithm 2&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;332&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjpjF4/btqWWs00xX7/T91kZ4w0VaHIC49HoOLkGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjpjF4/btqWWs00xX7/T91kZ4w0VaHIC49HoOLkGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjpjF4/btqWWs00xX7/T91kZ4w0VaHIC49HoOLkGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjpjF4%2FbtqWWs00xX7%2FT91kZ4w0VaHIC49HoOLkGK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;332&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;알고리즘 1의 문제를 보완하여 나온 것이 알고리즘 2이다.&lt;br /&gt;flag 배열 변수를 사용한다.&lt;br /&gt;자신의 flag 변수를 true로 만들어 주고 상대방의 flag 변수가 true이면 대기를 하게 되고 false이면 Critical Section에 접근하여 작업한 후 자신의 flag 변수를 false로 만들어 준다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;그러나 알고리즘 2 또한 문제가 있다.&lt;br /&gt;프로세스A가 flag를 true로 바꾼 상태에서 프로세스B에게 CPU가 넘어가게 되면 프로세스B 또한 자신의 flag를 true로 바꾸게 된다. 이렇게 되면 두 프로세스 모두 Critical Section에 들어가지 못한 상태로 무한 대기를 하게 된다.&lt;br /&gt;Progress를 만족하지 못한다.&lt;/p&gt;
&lt;h2&gt;5-3. Algorithm 3(Peterson's Algorithm)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;302&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0IZ5s/btqW1tdM2a2/KbxdEWakxKeb5tJ8CgvlZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0IZ5s/btqW1tdM2a2/KbxdEWakxKeb5tJ8CgvlZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0IZ5s/btqW1tdM2a2/KbxdEWakxKeb5tJ8CgvlZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0IZ5s%2FbtqW1tdM2a2%2FKbxdEWakxKeb5tJ8CgvlZ1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;302&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;알고리즘 3은 피터슨 알고리즘이다.&lt;br /&gt;flag와 turn 변수를 둘다 사용하게 된다. 피터슨 알고리즘은 3가지 충족 조건을 모두 만족한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;그러나 Busy Waiting(spin lock)문제가 발생할 수 있다.&lt;br /&gt;프로세스A가 계속해서 Critical Section에 접근한 상태에서 프로세스B로 CPU가 할당이 된다면 프로세스B는 접근하지 못하고 계속해서 자신의 CPU 할당 시간 동안 무한대기를 하게 되어 효율적인 동작을 하지 못한다.&lt;/p&gt;
&lt;h2&gt;5-4. Synchronization Hardware&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;382&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LNJMh/btqWX5K3t7z/MOVnKvJmENO42hAIKoUrI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LNJMh/btqWX5K3t7z/MOVnKvJmENO42hAIKoUrI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LNJMh/btqWX5K3t7z/MOVnKvJmENO42hAIKoUrI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLNJMh%2FbtqWX5K3t7z%2FMOVnKvJmENO42hAIKoUrI0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;382&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;H/W적으로 Critical Section 문제는 쉽게 해결될 수 있따.&lt;br /&gt;결국 Critical Section문제는 데이터를 메모리에서 읽는 것과 쓰는 것을 하나의 instruction으로 실행할 수 없기 때문에 발생하는 문제이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;위 문제를 해결해줄 Instruction으로 Test_and_set(a)가 있다.&lt;br /&gt;Test_and_set(a)은 a라는 값을 읽고 a를 1로 바꿔주는 것을 하나의 instruction으로 실행해주는 것이다.&lt;br /&gt;Test_and_set(a)이 지원된다면 코드로 복잡하게 알고리즘을 구현할 필요가 없다.&lt;/p&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/5</guid>
      <comments>https://immigrationssu.tistory.com/entry/11-Process-Synchronization-1#entry5comment</comments>
      <pubDate>Sat, 20 Mar 2021 21:17:32 +0900</pubDate>
    </item>
    <item>
      <title>8. CPU Scheduling</title>
      <link>https://immigrationssu.tistory.com/entry/8-CPU-Scheduling</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=aa53d6aa576466ee&quot;&gt;http://www.kocw.net/home/cview.do?lid=aa53d6aa576466ee&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;5-5. Multilevel Queue&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bK9qNE/btq0y1GiRgG/lZdQJKPzy3Nk6lpyNekiL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bK9qNE/btq0y1GiRgG/lZdQJKPzy3Nk6lpyNekiL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bK9qNE/btq0y1GiRgG/lZdQJKPzy3Nk6lpyNekiL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbK9qNE%2Fbtq0y1GiRgG%2FlZdQJKPzy3Nk6lpyNekiL0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;우선순위가 높을수록 위쪽에 위치하게 된다.&lt;br&gt;프로세스를 어느 우선순위에 배치시킬 것인지와 우선순위가 낮은 프로세스에 대한 Starvation 극복 방안을 고려해야 한다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pbdYK/btq0Ap0yrWp/qqLujzIgUV2JlPs0BsWhN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pbdYK/btq0Ap0yrWp/qqLujzIgUV2JlPs0BsWhN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pbdYK/btq0Ap0yrWp/qqLujzIgUV2JlPs0BsWhN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpbdYK%2Fbtq0Ap0yrWp%2FqqLujzIgUV2JlPs0BsWhN1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;이러한 극복방안으로 Ready queue를 여러 개로 분할시킬 수 있다.&lt;br&gt;아래 방식은 queue가 2개인 방식이다.&lt;br&gt;foreground queue에는 interactive한 job을 대기시키고 background queue에는 batch형 job을 대기시킨다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;그리고 각 queue는 독립적인 Scheduling 알고리즘을 가져야 한다.&lt;br&gt;foreground queue는 interactive한 job들이 대기하고 있기 때문에 속도가 중요하므로 Round Robin을 채택하고&lt;br&gt;background queue는 CPU만 잡아먹는 batch형 job들이 대기하고 있기 때문에 FCFS을 채택할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;그 다음 이제는 queue에 대한 Scheduling이 필요하다.&lt;br&gt;만약 우선순위를 강하게 적용하는 방식에서는 우선순위가 비어있지 않는 이상 아랫 순위에 CPU를 할당하기 어렵기 때문에&lt;br&gt;Starvation 현상을 겪을 수 있게 된다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;이러한 해결 방법으로 CPU time을 적절한 비율로 할당하여 주게 되면 Starvation은 발생하지 않게 된다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;5-6. Multilevel Feedback Queue&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CKdwE/btq0zc1VtIw/BkFP0HEIxLyJAfHCXH4Fb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CKdwE/btq0zc1VtIw/BkFP0HEIxLyJAfHCXH4Fb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CKdwE/btq0zc1VtIw/BkFP0HEIxLyJAfHCXH4Fb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCKdwE%2Fbtq0zc1VtIw%2FBkFP0HEIxLyJAfHCXH4Fb0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2UMbQ/btq0DsIKzfa/1a28smP4OK4pfCLybocGKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2UMbQ/btq0DsIKzfa/1a28smP4OK4pfCLybocGKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2UMbQ/btq0DsIKzfa/1a28smP4OK4pfCLybocGKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2UMbQ%2Fbtq0DsIKzfa%2F1a28smP4OK4pfCLybocGKK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;보통은 처음 들어온 프로세스는 우선순위가 높은 queue에 넣게 된다.&lt;br&gt;상위 queue일수록 time quantum은 짧게 된다.&lt;br&gt;할당시간이 최상위 queue에서 끝나게 되면 그 다음 하위 queue로 강등되게 된다.&lt;br&gt;최하위 queue는 FCFS를 사용하며 상위 queue들은 Round Robin을 사용하게 된다.&lt;br&gt;CPU 사용시간이 짧은 프로세스들에게 우선순위를 많이 주는 스케줄링 방식이다.&lt;br&gt;&lt;br/&gt;&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zxHHj/btq0y0tSoqB/qiV8yCjaympPwfnqUvQST0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zxHHj/btq0y0tSoqB/qiV8yCjaympPwfnqUvQST0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zxHHj/btq0y0tSoqB/qiV8yCjaympPwfnqUvQST0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzxHHj%2Fbtq0y0tSoqB%2FqiV8yCjaympPwfnqUvQST0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;6. Multiple-Processor Scheduling&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SLXsW/btq0zZuekdk/IzKb4hCksTrnegG6f8UGK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SLXsW/btq0zZuekdk/IzKb4hCksTrnegG6f8UGK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SLXsW/btq0zZuekdk/IzKb4hCksTrnegG6f8UGK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSLXsW%2Fbtq0zZuekdk%2FIzKb4hCksTrnegG6f8UGK0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;CPU가 여러개 일 경우 Load Sharing이 필요하다.&lt;br&gt;특정 CPU 1개만 일을 해서는 안된다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;7. Real-Time Scheduling&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqiSuG/btq0Dsor7Ja/xWmaqN5Pr2zJHukYAWXISK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqiSuG/btq0Dsor7Ja/xWmaqN5Pr2zJHukYAWXISK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqiSuG/btq0Dsor7Ja/xWmaqN5Pr2zJHukYAWXISK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqiSuG%2Fbtq0Dsor7Ja%2FxWmaqN5Pr2zJHukYAWXISK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;RTOS는 deadline이 보장되어야 하기 때문에 미리 Scheduling을 해놓게 된다.&lt;br&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;8. Thread Scheduling&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIHGYA/btq0zYPGnVi/bvE3RmwTnjHc5bI1RiemE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIHGYA/btq0zYPGnVi/bvE3RmwTnjHc5bI1RiemE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIHGYA/btq0zYPGnVi/bvE3RmwTnjHc5bI1RiemE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIHGYA%2Fbtq0zYPGnVi%2FbvE3RmwTnjHc5bI1RiemE1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Local Scheduling : 운영체제가 CPU를 어떤 프로세스에게 할당할지만 결정하고 Thread의 경우는 프로세스 내부에서 알아서 Scheduling을 결정한다.&lt;/li&gt;
&lt;li&gt;Global Scheduling : 운영체제가 Thread의 존재를 알고 있어 운영체제가 어떤 Thread에게 CPU를 할당할지 결정한다.&lt;br/&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;9. Algorithm Evaluation&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRDAE8/btq0zvNIEVj/klL5e2tFAkBrLZKzNKhc4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRDAE8/btq0zvNIEVj/klL5e2tFAkBrLZKzNKhc4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRDAE8/btq0zvNIEVj/klL5e2tFAkBrLZKzNKhc4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRDAE8%2Fbtq0zvNIEVj%2FklL5e2tFAkBrLZKzNKhc4k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Queueing models : 프로세스 도착율과 CPU의 처리율등을 통해 계산을 한다, 이론적으로 많이 사용하는 방식이다.&lt;/li&gt;
&lt;li&gt;Implementation &amp;amp; Mesasurement : 실제 시스템에 구현하여 실제 작업에 대해 성능을 측정 비교한다, Queueing Models과 상반된다.&lt;/li&gt;
&lt;li&gt;Simulation : Implementation &amp;amp; Mesasurement는 직접하기 어렵기 때문에 많이 사용되는 방법이다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/11</guid>
      <comments>https://immigrationssu.tistory.com/entry/8-CPU-Scheduling#entry11comment</comments>
      <pubDate>Sat, 20 Mar 2021 21:16:39 +0900</pubDate>
    </item>
    <item>
      <title>7. CPU Scheduling 1</title>
      <link>https://immigrationssu.tistory.com/entry/7-CPU-Scheduling-1</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;br /&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br /&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br /&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=5488703b25305c37&quot;&gt;http://www.kocw.net/home/cview.do?lid=5488703b25305c37&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. CPU-burst Time&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;420&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5GGSw/btqZ2cmCRrp/sWIboyNK0LKtUp4LN5bF01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5GGSw/btqZ2cmCRrp/sWIboyNK0LKtUp4LN5bF01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5GGSw/btqZ2cmCRrp/sWIboyNK0LKtUp4LN5bF01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5GGSw%2FbtqZ2cmCRrp%2FsWIboyNK0LKtUp4LN5bF01%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;420&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;프로그램의 경로는 CPU만 연속적으로 사용하는 단계와 I/O를 사용하는 단계가 번갈아가면서 실행되는 것이다.&lt;br /&gt;CPU에서 Instruction을 실행하는 단계를 CPU burst라고 하며 I/O를 쓰는 단계를 I/O burst라고 한다.&lt;br /&gt;프로그램의 종류마다 CPU burst와 I/O burst가 나타나는 주기는 다르다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;522&quot; data-origin-height=&quot;438&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1jWCn/btqZ2aWBrUt/Jl0FQPaOFFVIFkMNEzTPRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1jWCn/btqZ2aWBrUt/Jl0FQPaOFFVIFkMNEzTPRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1jWCn/btqZ2aWBrUt/Jl0FQPaOFFVIFkMNEzTPRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1jWCn%2FbtqZ2aWBrUt%2FJl0FQPaOFFVIFkMNEzTPRK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;522&quot; data-origin-height=&quot;438&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;I/O bound job이란 CPU를 짧게 사용하고 I/O burst가 자주 끼어드는 비중이 높은 것을 말한다.&lt;br /&gt;CPU bound job이란 CPU를 오래 사용하고 I/O burst를 자주 사용하지 않는 것을 말한다.&lt;br /&gt;실제로 CPU는 CPU bound job 비중이 높으며 I/O bound job은 빈도가 많지만 CPU를 사용하는 비중이 낮다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;CPU Scheduling이 필요한 이유는 I/O bound job 때문이다.&lt;br /&gt;사람과 연결된 interative한 job을 우선순위로 두어야 한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;CPU Scheduling은 2가지의 중요한 이슈가 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;누구에게 우선해서 CPU 소유권을 줄 것인가&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;언제 얼마만큼의 시간을 주고 뺐을 것인가&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;2. 프로세스의 특성 분류&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;522&quot; data-origin-height=&quot;303&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/en0fe9/btqZ4A8lydt/xCs9TGcTdGSEPfD8mj4SP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/en0fe9/btqZ4A8lydt/xCs9TGcTdGSEPfD8mj4SP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/en0fe9/btqZ4A8lydt/xCs9TGcTdGSEPfD8mj4SP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fen0fe9%2FbtqZ4A8lydt%2FxCs9TGcTdGSEPfD8mj4SP0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;522&quot; data-origin-height=&quot;303&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;3. CPU Scheduler &amp;amp; Dispatcher&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;369&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6vldA/btqZYm5mvBg/yk4PGuVjcUiFGroA0j5Nc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6vldA/btqZYm5mvBg/yk4PGuVjcUiFGroA0j5Nc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6vldA/btqZYm5mvBg/yk4PGuVjcUiFGroA0j5Nc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6vldA%2FbtqZYm5mvBg%2Fyk4PGuVjcUiFGroA0j5Nc1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;369&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;CPU Scheduler는 누구에게 CPU를 줄 것인지 결정하는 운영체제(kernel) 코드이다.&lt;br /&gt;Dispatcher는 CPU를 누구에게 줄지 결정되었으면 CPU를 전달해주는 역할을 하는 운영체제(kernel) 코드로&lt;br /&gt;CPU에서 돌아가던 프로세스의 Context를 저장하고 새로 CPU를 넘겨주는 프로세스의 Context를 CPU 레지스터에 설정해놓는다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;CPU Scheduling이 필요한 경우는 다음과 같은 상태 변화가 있은 경우이다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Running -&amp;gt; Blocked&lt;br /&gt;nonpreemptive&lt;br /&gt;ex) I/O를 요청하는 시스템 콜&lt;/li&gt;
&lt;li&gt;Running -&amp;gt; Ready&lt;br /&gt;preemtive&lt;br /&gt;ex) CPU 소유권 할당시간 만료로 인한 timer Interrupt&lt;/li&gt;
&lt;li&gt;Blocked -&amp;gt; Ready&lt;br /&gt;preemtive&lt;br /&gt;ex) I/O 완료 후 Interrupt&lt;br /&gt;I/O가 끝났을 때는 Ready로 보내고 CPU를 바로 할당해주지는 않는다.&lt;br /&gt;그러나 CPU를 바로 넘겨줄 때도 있다.&lt;br /&gt;(ex. 우선순위 CPU Scheduling에서 I/O를 요청한 프로세스가 우선순위가 가장 높을 경우)&lt;/li&gt;
&lt;li&gt;Terminate&lt;br /&gt;nonpreemptive&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;nonpreemptive : 비선점형, 강제로 빼앗지 않고 자진 반납&lt;/li&gt;
&lt;li&gt;preemptive : 선점형, 강제로 빼았음, 현대적인 CPU Scheduling&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;4. Scheduling Criteria&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;395&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC1mor/btqZYmXWaHx/nCgOj5uzE9F0FfuacXm7G1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC1mor/btqZYmXWaHx/nCgOj5uzE9F0FfuacXm7G1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC1mor/btqZYmXWaHx/nCgOj5uzE9F0FfuacXm7G1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC1mor%2FbtqZYmXWaHx%2FnCgOj5uzE9F0FfuacXm7G1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;395&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;시스템 입장에서의 성능 척도 : 이용률, 처리량&lt;/li&gt;
&lt;li&gt;프로그램 입장에서의 성능 척도 : 소요시간, 대기시간, 응답시간&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;CPU uillization(이용률)&lt;br /&gt;전체시간에서 CPU가 일한 시간을 뜻한다.&lt;br /&gt;가능한 CPU를 바쁘게 일을 시켜야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Throughput(처리량)&lt;br /&gt;주어진 시간동안 몇 개의 작업을 완료하였는지를 뜻한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Turnaround time(소요시간)&lt;br /&gt;CPU burst를 다 사용하고 나가는 시간을 뜻한다.&lt;br /&gt;CPU burst에서 CPU를 쓴 시간과 기다리는 시간의 총합&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Waiting time(대기시간)&lt;br /&gt;CPU burst를 기다리는 시간을 뜻한다.&lt;br /&gt;한번의 CPU burst안에서 CPU를 얻었다가 뺏겨서 기다리는 시간의 총합&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Response time(응답시간)&lt;br /&gt;처음으로 CPU를 얻기까지의 시간을 뜻한다.&lt;br /&gt;CPU burst에서 처음으로 CPU를 얻기까지의 시간&lt;br /&gt;time-sharing을 사용하는 환경에서는 처음으로 CPU를 얻는 시간은 사용자 응답과 관련하여 굉장히 중요한 시간이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;preemptive Scheduling은 CPU를 얻었다고 해서 끝까지 사용할 수 있는 것은 아니다.&lt;br /&gt;시간의 개념과 프로세스의 개수는 프로세스가 시작돼서 종료되는 것이 아닌 매 CPU burst건에 한해서&lt;br /&gt;CPU Scheduling의 대상이 되는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;5. Scheduling Algorithms&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;386&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvgBJN/btqZ0tWlHTw/TGlVG1JIwJTPHdj8CUkvCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvgBJN/btqZ0tWlHTw/TGlVG1JIwJTPHdj8CUkvCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvgBJN/btqZ0tWlHTw/TGlVG1JIwJTPHdj8CUkvCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvgBJN%2FbtqZ0tWlHTw%2FTGlVG1JIwJTPHdj8CUkvCK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;386&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;5-1. FCFS(First-Come First-Served)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;301&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mfhOc/btqZYlL7h7K/9uufgzntBYecpYLyYlfNiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mfhOc/btqZYlL7h7K/9uufgzntBYecpYLyYlfNiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mfhOc/btqZYlL7h7K/9uufgzntBYecpYLyYlfNiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmfhOc%2FbtqZYlL7h7K%2F9uufgzntBYecpYLyYlfNiK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;301&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;301&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rXWjF/btqZ3eR0CRj/U5XcSzd7O6OUFU7y88qfik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rXWjF/btqZ3eR0CRj/U5XcSzd7O6OUFU7y88qfik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rXWjF/btqZ3eR0CRj/U5XcSzd7O6OUFU7y88qfik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrXWjF%2FbtqZ3eR0CRj%2FU5XcSzd7O6OUFU7y88qfik%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;301&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;먼저 들어온 순서대로 처리하는 것을 말한다.&lt;br /&gt;nonpreemptive Scheduling으로 효율성이 떨어진다.&lt;br /&gt;맨 처음 어떤 프로세스가 선점하느냐에 따라서 대기시간이 천차만별이다.&lt;br /&gt;긴 프로세스가 도착해서 짧은 프로세스들이 오래기다리는 것을 Convoy effect라고 한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;5-2.SJF(Shortest-Job-First)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;417&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2RWZJ/btqZ1bCeR37/10KPC6Ix6aZk75KVWz0KRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2RWZJ/btqZ1bCeR37/10KPC6Ix6aZk75KVWz0KRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2RWZJ/btqZ1bCeR37/10KPC6Ix6aZk75KVWz0KRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2RWZJ%2FbtqZ1bCeR37%2F10KPC6Ix6aZk75KVWz0KRk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;417&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;CPU를 짧게 쓰는 프로세스에게 먼저 CPU를 한당하는 것을 말한다.(CPU burst가 제일 짧은 것)&lt;br /&gt;preemptive 기준으로 대기시간이 줄어들게 되고 제일 짧은 average 대기시간을 보장한다.&lt;br /&gt;preemptive 버전은 SRTF라고도 부른다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;기존에 CPU를 사용하고 있는 프로세스보다 더 짧게 사용하는 프로세스가 들어올 때&lt;br /&gt;CPU를 넘겨주는 것이기 때문에 기존에 CPU를 사용한 프로세스들 중에서도 제일 짧은 프로세스에게 CPU를 넘겨주게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;390&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmc4iQ/btqZ7J5hPPc/f414Vm9uWsIIrzGakciMB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmc4iQ/btqZ7J5hPPc/f414Vm9uWsIIrzGakciMB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmc4iQ/btqZ7J5hPPc/f414Vm9uWsIIrzGakciMB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcmc4iQ%2FbtqZ7J5hPPc%2Ff414Vm9uWsIIrzGakciMB1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;390&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;394&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U6NIl/btqZ4A1T3s8/aIbwYN6EK8uP8Z4EzJgoO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U6NIl/btqZ4A1T3s8/aIbwYN6EK8uP8Z4EzJgoO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U6NIl/btqZ4A1T3s8/aIbwYN6EK8uP8Z4EzJgoO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU6NIl%2FbtqZ4A1T3s8%2FaIbwYN6EK8uP8Z4EzJgoO0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;394&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;SJF는 극단적으로 CPU 사용이 짧은 JOB을 선호하기 때문에 CPU 사용이 긴 프로세스는 영원히 CPU를 사용하지 못할 수 있다.&lt;br /&gt;이러한 현상을 Starvation(기아) 현상이라 한다.&lt;br /&gt;프로세스가 CPU 사용시간을 미리 알 수 없다.&lt;br /&gt;과거의 데이터를 통해 사용시간을 예측할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;361&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kEXVA/btqZ3eZgn16/dVgFOIE4EMb6Sr1oj1Iyv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kEXVA/btqZ3eZgn16/dVgFOIE4EMb6Sr1oj1Iyv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kEXVA/btqZ3eZgn16/dVgFOIE4EMb6Sr1oj1Iyv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkEXVA%2FbtqZ3eZgn16%2FdVgFOIE4EMb6Sr1oj1Iyv1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;361&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;실제 CPU 사용시간.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;CPU 사용시간을 예측한 시간&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;405&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bls6n2/btqZZThIZby/Rk136XKXVcHLbUjR896eO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bls6n2/btqZZThIZby/Rk136XKXVcHLbUjR896eO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bls6n2/btqZZThIZby/Rk136XKXVcHLbUjR896eO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbls6n2%2FbtqZZThIZby%2FRk136XKXVcHLbUjR896eO1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;405&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;5-3. Priority Scheduling&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;386&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3JOY7/btqZ7KXqyHz/vt8e5OhOZlvFdqZORIM8E1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3JOY7/btqZ7KXqyHz/vt8e5OhOZlvFdqZORIM8E1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3JOY7/btqZ7KXqyHz/vt8e5OhOZlvFdqZORIM8E1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3JOY7%2FbtqZ7KXqyHz%2Fvt8e5OhOZlvFdqZORIM8E1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;386&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;우선순위 Scheduling을 뜻한다.&lt;br /&gt;우선순위가 제일 높은 프로세스에게 CPU를 넘겨주게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이 Scheduling은 preemptive 버전과 nonpreemptive 버전으로 나눌 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;preemptvie : 현재 실행되고 있는 프로세스보다 우선순위가 더 높은 순위의 프로세스가 있다면 바로 CPU를 넘겨줌&lt;/li&gt;
&lt;li&gt;nonpreemptive : 현재 실행되고 있는 프로세스는 다 실행할 동안 CPU를 보장해주고 완료가 되면 우선순위에 따라 CPU를 넘겨줌&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;우선순위가 높지않은 프로세스는 Starvation 현상을 겪을 수 있다.&lt;br /&gt;이러한 해결법으로는 Aging(노화)이 있다.&lt;/li&gt;
&lt;li&gt;Aging : 아무리 우선수위가 낮더라도 대기시간만큼 우선순위를 높여줌&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5-4. Round Robin(RR)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;370&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOOJvm/btqZ7KC8upP/ztbDgh7lsk5kdv0AleC4Zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOOJvm/btqZ7KC8upP/ztbDgh7lsk5kdv0AleC4Zk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOOJvm/btqZ7KC8upP/ztbDgh7lsk5kdv0AleC4Zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOOJvm%2FbtqZ7KC8upP%2FztbDgh7lsk5kdv0AleC4Zk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;370&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;현대적인 CPU Scheduling으로 preemptive Scheduling이다.&lt;br /&gt;CPU 응답시간(response time)이 빨라진다.&lt;br /&gt;대기시간이 CPU를 사용하려는 시간에 비례하게 된다.&lt;br /&gt;할당시간이 길게 되면 FCFS와 같아지게 되고&lt;br /&gt;할당시간이 짧게 되면 Context Switch overhead가 커지게 된다. 즉, 시스템 전체 성능이 낮아지게 된다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;409&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/da19Nq/btqZ6imzWwy/1YXMntNMstdJhdzKFdk6FK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/da19Nq/btqZ6imzWwy/1YXMntNMstdJhdzKFdk6FK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/da19Nq/btqZ6imzWwy/1YXMntNMstdJhdzKFdk6FK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fda19Nq%2FbtqZ6imzWwy%2F1YXMntNMstdJhdzKFdk6FK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;409&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;443&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lfHfM/btqZ2ctIzCC/ZwywQlii2kgHKKZKgeUIA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lfHfM/btqZ2ctIzCC/ZwywQlii2kgHKKZKgeUIA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lfHfM/btqZ2ctIzCC/ZwywQlii2kgHKKZKgeUIA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlfHfM%2FbtqZ2ctIzCC%2FZwywQlii2kgHKKZKgeUIA0%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;443&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;CPU 사용시간이 모두 동일한 프로그램이 있을 때 FCFS는 적어도 1개의 프로세스만이라도 빨리 사용하고&lt;br /&gt;나갈 수 있지만 Round Robin일 경우 동일한 대기시간을 가지고 동시에 프로세스가 나가게 된다.&lt;br /&gt;이럴 경우 Round Robin 방식이 더 안좋을 수 있다.&lt;br /&gt;그러나 일반적으로는 CPU 사용시간이 동일하지 않기 때문에 Round Robin이 효율적이다.&lt;br /&gt;Round Robin은 Turnaround Time보다 Response Time이 짧아진다는 것에 장점이 있다.&lt;/p&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/10</guid>
      <comments>https://immigrationssu.tistory.com/entry/7-CPU-Scheduling-1#entry10comment</comments>
      <pubDate>Sun, 14 Mar 2021 21:06:02 +0900</pubDate>
    </item>
    <item>
      <title>6. Process Management</title>
      <link>https://immigrationssu.tistory.com/entry/6-Process-Management</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=b988d89cb0bc07b3&quot;&gt;http://www.kocw.net/home/cview.do?lid=b988d89cb0bc07b3&lt;/a&gt;, &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=3a5437eaa6c9e5b0&quot;&gt;http://www.kocw.net/home/cview.do?lid=3a5437eaa6c9e5b0&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. 프로세스 생성&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUYU88/btqZn1UTMAg/EiSQgEMYAlQUR2tfxq97OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUYU88/btqZn1UTMAg/EiSQgEMYAlQUR2tfxq97OK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUYU88/btqZn1UTMAg/EiSQgEMYAlQUR2tfxq97OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUYU88%2FbtqZn1UTMAg%2FEiSQgEMYAlQUR2tfxq97OK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;부모 프로세스 하나가 자식 프로세스를 여러 개 낳을 수 있으며 트리를 형성한다.&lt;br&gt;보통 부모 프로세스와 자식 프로세스 사이는 경쟁상대가 되기 때문에 자원을 공유하지 않는다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;부모 프로세스와 자식 프로세스가 주소 공간을 공유하지 않는 것이 원칙이지만&lt;br&gt;리눅스에서는 일단 주소 공간을 공유하게 되어있다.&lt;br&gt;PC(Program Counter)만 복사하여 똑같은 위치를 가르키게 된다.&lt;br&gt;그런 다음 자식 프로세스는 각자의 길을 가게 되면서 주소 공간을 복사하여 사용하게 된다.&lt;br&gt;이것을 &lt;strong&gt;Copy on Write(COW)&lt;/strong&gt; 기법 이라고 한다.(Write가 발생했을 때 주소공간을 Copy)&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt9Uzn/btqZoykBxVD/qGnvMiN2Qmkea1ru3rILsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt9Uzn/btqZoykBxVD/qGnvMiN2Qmkea1ru3rILsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt9Uzn/btqZoykBxVD/qGnvMiN2Qmkea1ru3rILsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt9Uzn%2FbtqZoykBxVD%2FqGnvMiN2Qmkea1ru3rILsK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;프로세스의 생성은 부모 프로세스를 복제하여 프로그램을 덮어씌우는 단계로 수행되며&lt;br&gt;운영체제를 통해서만 프로세스 생성이 가능하다.&lt;br&gt;프로세스가 운영체제에게 자식을 낳아 달라고 부탁을 해서 운영체제가 대신 낳아주는 형태인 것이다.(fork() 시스템 콜)&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fork() : 프로세스 복제&lt;/li&gt;
&lt;li&gt;exec() : 새로운 프로그램을 덮어 씌움&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. 프로세스 종료&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cl78vU/btqZpfZnHUV/hkOWduVN0hMdiztQbDBnqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cl78vU/btqZpfZnHUV/hkOWduVN0hMdiztQbDBnqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cl78vU/btqZpfZnHUV/hkOWduVN0hMdiztQbDBnqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcl78vU%2FbtqZpfZnHUV%2FhkOWduVN0hMdiztQbDBnqK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;프로세스 종료는 2가지가 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;exit&lt;br&gt; 프로세스 종료 시스템콜, 자식이 부모에게 output data를 보내는 자발적 종료&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;abort&lt;br&gt; 강제적 종료&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;프로세스는 자식 프로세스가 먼저 종료된 후 부모 프로세스가 마지막으로 종료되어야 한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3. 프로세스와 관련한 시스템 콜&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/P4h7e/btqZrfRTqBG/j4GHRK4pIZ6XaAAs1AzK61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/P4h7e/btqZrfRTqBG/j4GHRK4pIZ6XaAAs1AzK61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/P4h7e/btqZrfRTqBG/j4GHRK4pIZ6XaAAs1AzK61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP4h7e%2FbtqZrfRTqBG%2Fj4GHRK4pIZ6XaAAs1AzK61%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;3-1. fork() 시스템 콜&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bL4rIg/btqZlQMQALh/KxiP0eWh4z1YTX4qJi4nJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bL4rIg/btqZlQMQALh/KxiP0eWh4z1YTX4qJi4nJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bL4rIg/btqZlQMQALh/KxiP0eWh4z1YTX4qJi4nJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbL4rIg%2FbtqZlQMQALh%2FKxiP0eWh4z1YTX4qJi4nJ1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;예를 들어 위와 같은 C언어 코드가 있다.&lt;br&gt;부모 프로세스에서 pid = fork(); 줄이 실행되면 똑같은 자식 프로세스를 만들게 되고&lt;br&gt;부모 프로세스는 그 다음 코드를 실행하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;생성된 자식 프로세스는 int pid; 부터 실행되는 것이 아닌 pid = fork()부터 실행하게 된다.&lt;br&gt;왜냐하면 부모 프로세스의 Program Counter가 pid = for()를 가리킨 상태에서 복제하였기 때문이다.&lt;br&gt;그러나 자식 프로세스 또한 부모 프로세스와 동일한 코드를 가지고 있어 구분이 어렵게 된다.&lt;br&gt;이럴 경우에는 pid에 반환된 값을 통해 판단할 수 있다.&lt;br&gt;부모 프로세스는 양수를 반환받게 되며 자식 프로세스는 0을 반환받게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;3-2. exec() 시스템 콜&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpHlU8/btqZpgqtb2s/T3dBJVeO5d5F2yNr96kMK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpHlU8/btqZpgqtb2s/T3dBJVeO5d5F2yNr96kMK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpHlU8/btqZpgqtb2s/T3dBJVeO5d5F2yNr96kMK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpHlU8%2FbtqZpgqtb2s%2FT3dBJVeO5d5F2yNr96kMK0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;exelp 명령어를 통해 exec() 시스템 콜을 실행할 수 있다.&lt;br&gt;위 코드에서는 자식 프로세스가 &amp;quot;/bin/date&amp;quot;라는 프로그램으로 덮어 씌어진것이다.&lt;br&gt;exec()을 사용하게 되면 다시 원 상태로 돌아올 수 없다.&lt;br&gt;꼭 자식 프로세스를 만들어서 exec()을 사용할 필요는 없기 때문에 fork()를 사용하지 않아도 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;3-3. wait() 시스템 콜&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9KBIp/btqZpf6cGwx/IiGbtNUibLueNA5AUDFXRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9KBIp/btqZpf6cGwx/IiGbtNUibLueNA5AUDFXRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9KBIp/btqZpf6cGwx/IiGbtNUibLueNA5AUDFXRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9KBIp%2FbtqZpf6cGwx%2FIiGbtNUibLueNA5AUDFXRk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;wait() 시스템 콜은 자식 프로세스가 종료될 때까지 기다리는 시스템 콜이다.(block 상태)&lt;br&gt;예를 들어 리눅스 쉘에서 프로그램 이름을 기입하고 엔터를 치면 해당 프로그램이 실행되며&lt;br&gt;쉘에는 프로그램이 종료될 때까지 아무것도 기입할 수가 없게 된다.&lt;br&gt;왜냐하면 쉘도 하나의 프로그램이기 때문이다.&lt;br&gt;쉘에서도 프로그램을 실행하면 그 프로그램은 일종의 자식 프로그램이며&lt;br&gt;쉘이 wait() 시스템 콜로 인해 block 상태가 되는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;3-4. exit() 시스템 콜&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uoNEE/btqZpfd2XjX/vwYl6Efpzcaogmh50r7NK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uoNEE/btqZpfd2XjX/vwYl6Efpzcaogmh50r7NK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uoNEE/btqZpfd2XjX/vwYl6Efpzcaogmh50r7NK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuoNEE%2FbtqZpfd2XjX%2FvwYl6Efpzcaogmh50r7NK0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;비자발적 종료 : 외부적인 요인으로 인한 종료&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;4. 프로세스간 협력(IPC)&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uoD7x/btqZpUtXyYT/Ne7GewH5TkXWTkEtW3Xp3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uoD7x/btqZpUtXyYT/Ne7GewH5TkXWTkEtW3Xp3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uoD7x/btqZpUtXyYT/Ne7GewH5TkXWTkEtW3Xp3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuoD7x%2FbtqZpUtXyYT%2FNe7GewH5TkXWTkEtW3Xp3K%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;프로세스간 협력 메커니즘(IPC)는 프로세스간 정보를 주고 받을 수 있는 방법을 뜻한다.&lt;br&gt;프로세스는 원칙적으로 독립적이기 때문에 메세지를 전달할 수 있는 방법이 없다.&lt;br&gt;그러나 kernel을 통해 메시지를 전달할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;프로세스는 독립적인 주소공간을 갖기 때문에 자신의 주소공간만 볼 수 있다.&lt;br&gt;그러나 그럼에도 불구하고 shared memory는 서로 다른 프로세스가 일부 주소공간을 공유할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Thread는 CPU 수행 단위이기 때문에 하나의 프로세스의 주소공간을 공유하고 있으므로 협력이 쉽다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;4-1. Message Passing&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYFcXc/btqZpgqt6Gi/Gt8fHIMP4wCtCFXcHW80I1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYFcXc/btqZpgqt6Gi/Gt8fHIMP4wCtCFXcHW80I1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYFcXc/btqZpgqt6Gi/Gt8fHIMP4wCtCFXcHW80I1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYFcXc%2FbtqZpgqt6Gi%2FGt8fHIMP4wCtCFXcHW80I1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Message Passing은 2가지 방법이 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;통신하려는 프로세스의 이름을 명시하는 여부에 따라 &lt;strong&gt;직접&lt;/strong&gt;, &lt;strong&gt;간접&lt;/strong&gt;으로 나뉘게 된다.&lt;br&gt;2가지 방법 모두 kernel을 통해 전달하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Direct Communication(직접)&lt;br&gt; 특정 대상에게 메시지를 전달한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Indirect Communication(간접)&lt;br&gt; Mailbox에 메시지를 넣기 때문에 아무 대상에게 메시지를 전달한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;4-2. Shared Memory&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSvRfI/btqZn0ho3fn/bbEJ9qRtgM9eB26G4u95tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSvRfI/btqZn0ho3fn/bbEJ9qRtgM9eB26G4u95tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSvRfI/btqZn0ho3fn/bbEJ9qRtgM9eB26G4u95tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSvRfI%2FbtqZn0ho3fn%2FbbEJ9qRtgM9eB26G4u95tk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;위 그림으로 예를 들어 프로세스A와 프로세스B는 주소공간이 서로 독립적으로 존재하지만&lt;br&gt;물리적인 메모리에 Mapping할 때 두 프로세스의 일부 영역을 공유되도록 Mapping을 시켜 놓는 것이다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Shared Memory도 마찬가지로 Kernel에게 Shared Memory 관련 시스템 콜을 해서 메모리에 Mapping 해놓은 다음에&lt;br&gt;사용자 프로세스끼리 공유 영역을 사용할 수 있는 것이다.&lt;br&gt;Shared Memory는 프로세스간 신뢰가 높아야 한다.&lt;/p&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/9</guid>
      <comments>https://immigrationssu.tistory.com/entry/6-Process-Management#entry9comment</comments>
      <pubDate>Sun, 7 Mar 2021 21:18:38 +0900</pubDate>
    </item>
    <item>
      <title>5. Process 2~3</title>
      <link>https://immigrationssu.tistory.com/entry/5-Process-23</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=29d9a718cff884c3&quot;&gt;http://www.kocw.net/home/cview.do?lid=29d9a718cff884c3&lt;/a&gt;, &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=54e1a4abcd59272d&quot;&gt;http://www.kocw.net/home/cview.do?lid=54e1a4abcd59272d&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;1. Thread&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2Jywq/btqZpgwNBJE/PXP2qb0Q5WdX75PlMEXYm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2Jywq/btqZpgwNBJE/PXP2qb0Q5WdX75PlMEXYm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2Jywq/btqZpgwNBJE/PXP2qb0Q5WdX75PlMEXYm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2Jywq%2FbtqZpgwNBJE%2FPXP2qb0Q5WdX75PlMEXYm1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;strong&gt;Thread&lt;/strong&gt;란 CPU를 수행하는 단위를 뜻한다, 가벼운 Process라고 부르기도 한다.&lt;br&gt;Process 내부의 Thread가 여러개 있는 경우, Thread가 Process 내부에서 공유하는 것들을 &lt;strong&gt;task&lt;/strong&gt;라고 칭한다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z7OwI/btqZpf5L8cM/iQS6bkd4sQbGGG2HMAEQF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z7OwI/btqZpf5L8cM/iQS6bkd4sQbGGG2HMAEQF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z7OwI/btqZpf5L8cM/iQS6bkd4sQbGGG2HMAEQF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ7OwI%2FbtqZpf5L8cM%2FiQS6bkd4sQbGGG2HMAEQF1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cu19Gt/btqZrgCPtOH/K3vDc1Jz2U0fMw6qEwKZvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cu19Gt/btqZrgCPtOH/K3vDc1Jz2U0fMw6qEwKZvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cu19Gt/btqZrgCPtOH/K3vDc1Jz2U0fMw6qEwKZvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcu19Gt%2FbtqZrgCPtOH%2FK3vDc1Jz2U0fMw6qEwKZvk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;동일한 일을 수행하는 Process가 여러 개 있을 경우 Process의 주소공간이 여러 개가 만들어지게 된다.&lt;br&gt;이러한 현상은 메모리를 낭비할 수 있다.&lt;br&gt;Thread는 Process 하나에서 공유할 수 있는 것은 최대한 공유하고 CPU 수행 관련 정보(PC, registers, stack)은 별도로 가지고 있게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biy4fa/btqZrfYeu5G/O2mwS0fUetCjvm4NqWi3HK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biy4fa/btqZrfYeu5G/O2mwS0fUetCjvm4NqWi3HK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biy4fa/btqZrfYeu5G/O2mwS0fUetCjvm4NqWi3HK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbiy4fa%2FbtqZrfYeu5G%2FO2mwS0fUetCjvm4NqWi3HK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;예를 들어 네트워크를 통해 웹페이지를 불러올 때(이것 또한 I/O 작업) 다중 Thread 구조로 해놓으면&lt;br&gt;하나의 Thread가 웹서버에서 그림파일을 불러옴과 동시에 다른 Thread는 텍스트를 불러오게 된다.&lt;br&gt;이럴 경우 먼저 처리가 완료된 것 부터 표출되기 때문에 사용자는 기다리는 시간이 줄어들어 빠른 응답성을 제공받게 된다.&lt;br&gt;만약 웹페이지를 불러오는 것을 Thread가 아닌 Process 단위로 나누어 놓게 되면&lt;br&gt;동일한 일을 하게 되는데 메모리 낭비가 발생하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;CPU가 1개가 아닌 여러 개를 사용할 경우 Thread를 사용하면 병렬성을 높일 수 있다.&lt;br&gt;예를 들어 1000 x 1000 연산 작업을 수행할 때 행과 열을 곱하는 것을 Thread로 만들어 CPU가 각각 연산을 처리하고&lt;br&gt;더하게 되면 더 빠른 결과를 도출할 수 있다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. Benefits of Threads&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V6FGB/btqZpfLseTQ/33gMPlJwM4g6qUk8WnDzX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V6FGB/btqZpfLseTQ/33gMPlJwM4g6qUk8WnDzX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V6FGB/btqZpfLseTQ/33gMPlJwM4g6qUk8WnDzX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV6FGB%2FbtqZpfLseTQ%2F33gMPlJwM4g6qUk8WnDzX0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Thread의 장점은 아래와 같다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Resonsiveness(응답성)&lt;br&gt; ex) 웹 페이지를 불러올 때&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resource Sharing(자원 공유)&lt;br&gt; 하나의 Process 안에서 Code, Data, Resource를 공유함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Economy(경제성)&lt;br&gt; Process 하나에 Thread를 추가하는 것은 Overhead가 크지 않으나 Process Context Switch는 Overhead가 높음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utilization of MP Architecctures(멀티프로세서 아키텍쳐 활용)&lt;br&gt; Thread가 서로 다른 CPU에서 병렬적으로 일을 할 수 있음(병렬성)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;3. Implementation of Threads&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJFoom/btqZpfLskVS/jq76ilEhafohFrH2FGy9eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJFoom/btqZpfLskVS/jq76ilEhafohFrH2FGy9eK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJFoom/btqZpfLskVS/jq76ilEhafohFrH2FGy9eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJFoom%2FbtqZpfLskVS%2Fjq76ilEhafohFrH2FGy9eK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Thread의 구현 방식은 아래와 같다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Kernel Threads&lt;br&gt; Thread가 여러 개 있다는 것을 Kernel이 알고 있는 것이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User Threads&lt;br&gt; Process 안에 Thread가 여러 개 있는 것을 Kernel은 모르고 사용자 프로그램이 스스로 라이브러리의 지원을 받아서&lt;br&gt; 여러 개의 Thread를 관리한다. -&amp;gt; 구현 상의 제약이 있을 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/8</guid>
      <comments>https://immigrationssu.tistory.com/entry/5-Process-23#entry8comment</comments>
      <pubDate>Sat, 6 Mar 2021 21:09:52 +0900</pubDate>
    </item>
    <item>
      <title>4. Process 1</title>
      <link>https://immigrationssu.tistory.com/entry/4-Process-1</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;br&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=b31830a2b3cf1e60&quot;&gt;http://www.kocw.net/home/cview.do?lid=b31830a2b3cf1e60&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. 프로세스의 개념&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;455&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6HBrv/btqYJ9Y7Z6p/56qS4eXChKLCKkpSZkHysk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6HBrv/btqYJ9Y7Z6p/56qS4eXChKLCKkpSZkHysk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6HBrv/btqYJ9Y7Z6p/56qS4eXChKLCKkpSZkHysk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6HBrv%2FbtqYJ9Y7Z6p%2F56qS4eXChKLCKkpSZkHysk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;455&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;프로세스란 실행중인 프로그램을 뜻한다.&lt;br&gt;프로세스 문맥(Context)은 프로세스의 현재 상태를 나타내는 모든 것을 뜻한다.&lt;br&gt;&lt;code&gt;EX) PC(Program Counter)가 어디를 가리키는지, 프로세스가 메모리에 어떤 것을 담고있는지, 현재 변수의 값은 얼마이며 프로그램이 실행되면서 CPU의 레지스터의 어떠한 값을 넣어 놓고 어떤 Instruction까지 실행했는지 등등&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;프로세스의 문맥(Context)는 크게 3가지가 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU 하드웨어 Context(주로 레지스터)&lt;/li&gt;
&lt;li&gt;프로세스의 주소 공간(Code, Data, Stack)&lt;/li&gt;
&lt;li&gt;OS(커널) 자료구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;프로세스들이 번갈아 가면서 실행되기 때문에 Context를 파악해놓는 것이 매우 중요하다.  &lt;/p&gt;
&lt;h1&gt;2. 프로세스의 상태&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;398&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oL8yP/btqYE6PgTj3/HgfDvkyqlgm4f6T10fKbc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oL8yP/btqYE6PgTj3/HgfDvkyqlgm4f6T10fKbc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oL8yP/btqYE6PgTj3/HgfDvkyqlgm4f6T10fKbc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoL8yP%2FbtqYE6PgTj3%2FHgfDvkyqlgm4f6T10fKbc1%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;398&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;프로세스는 상태(State)가 변경되며 수행된다.&lt;/p&gt;
&lt;p&gt;프로세스의 상태는 3가지가 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Running&lt;/li&gt;
&lt;li&gt;Ready&lt;/li&gt;
&lt;li&gt;Blocked&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;363&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1HUzS/btqYQwsplQQ/cCMf34eZMplKN2SFFpD5EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1HUzS/btqYQwsplQQ/cCMf34eZMplKN2SFFpD5EK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1HUzS/btqYQwsplQQ/cCMf34eZMplKN2SFFpD5EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1HUzS%2FbtqYQwsplQQ%2FcCMf34eZMplKN2SFFpD5EK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;363&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;프로세스는 실행하게 되면 CPU의 소유권을 얻기 위해 Ready인 상태로 대기하다 CPU 스케쥴러에 의해 CPU에 소유권을 얻게 되면 Running 상태로 바뀐다.&lt;br&gt;그러다 I/O나 특정 시스템 콜과 같은 Event를 요청하면 Blocked 상태가 되며 해당 Event가 완료되면 다시 CPU 소유권을 얻기 위해 Ready 상태로 변한다.&lt;br&gt;혹은 Running 상태에서 Timer Interrupt를 통해 다시 Ready 상태로 변한다.&lt;br&gt;그렇게 Ready 와 Running을 반복하다 프로세스 동작을 완료하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;456&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1nN3w/btqYQxrjc6F/6iVJPNni7hl2X1CwVYOrCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1nN3w/btqYQxrjc6F/6iVJPNni7hl2X1CwVYOrCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1nN3w/btqYQxrjc6F/6iVJPNni7hl2X1CwVYOrCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1nN3w%2FbtqYQxrjc6F%2F6iVJPNni7hl2X1CwVYOrCk%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;456&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;프로세스가 Blocked 상태일 때는 특정 Deivce(H/W) Queue에서 차례를 기다리게 된다.&lt;br&gt;H/W 뿐만 아니라 S/W 적으로 Blocked Queue가 형성될 수 있다(ex.공유데이터)&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;453&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmpUGc/btqYJ80cIT1/sX94ql4j5o6nK7idknryPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmpUGc/btqYJ80cIT1/sX94ql4j5o6nK7idknryPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmpUGc/btqYJ80cIT1/sX94ql4j5o6nK7idknryPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmpUGc%2FbtqYJ80cIT1%2FsX94ql4j5o6nK7idknryPK%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;453&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이러한 Queue들은 커널이 본인의 Data 영역에 자료구조로 만들어 놓게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3. Process Control Block(PCB)&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;417&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ggo5B/btqYLyj0nBI/hrZgWZd8PvlnyeSEE2I3ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ggo5B/btqYLyj0nBI/hrZgWZd8PvlnyeSEE2I3ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ggo5B/btqYLyj0nBI/hrZgWZd8PvlnyeSEE2I3ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGgo5B%2FbtqYLyj0nBI%2FhrZgWZd8PvlnyeSEE2I3ik%2Fimg.png&quot; width=&quot;100%&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;417&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;PCB란 운영체제가 각 프로세스를 관리하기 위한 프로세스당 유지하는 정보(자료구조)를 뜻한다.&lt;br&gt;PCB는 크게 4가지의 구성요소를 가진다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS가 관리상 사용하는 정보&lt;/li&gt;
&lt;li&gt;CPU 수행 관련 하드웨어 값&lt;/li&gt;
&lt;li&gt;메모리 관련&lt;/li&gt;
&lt;li&gt;파일 관련&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CPU는 Queue의 순서대로 실행되는 것 처럼 보이지만 프로세스마다 프로세스의 우선순위가 있어 우선순위가 높은 것부터 실행하게 된다.&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;4. 문맥 교환(Context Switch)&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFAGVJ/btqYIktKxe5/KMcgPro8oIRaTKSDoHZDbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFAGVJ/btqYIktKxe5/KMcgPro8oIRaTKSDoHZDbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFAGVJ/btqYIktKxe5/KMcgPro8oIRaTKSDoHZDbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFAGVJ%2FbtqYIktKxe5%2FKMcgPro8oIRaTKSDoHZDbk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;프로세스가 CPU 권한을 넘겨줄 때 CPU H/W 자체의 PC(Program Counter), 레지스터 상태, 메모리 맵을 커널의 해당 프로세스 PCB안에 저장을 시켜 놓는다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUrYah/btqYZ6tDFwJ/aiNOkNx5orEYvGfOB5vip0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUrYah/btqYZ6tDFwJ/aiNOkNx5orEYvGfOB5vip0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUrYah/btqYZ6tDFwJ/aiNOkNx5orEYvGfOB5vip0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUrYah%2FbtqYZ6tDFwJ%2FaiNOkNx5orEYvGfOB5vip0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Context Switch(문맥 교환)은 사용자 프로세스 하나로부터 또 다른 프로세스로 넘어가는 과정이다.&lt;br&gt;하지만 System Call이나 Interrupt 발생시 반드시 Context Switch가 일어나느 것은 아니다.&lt;/p&gt;
&lt;p&gt;예를 들어 프로세스A가 Interrupt나 System Call을 하게 되면 커널에게 CPU 권한이 넘어가게 되고&lt;br&gt;커널은 ISR이나 System Call 함수를 실행하게 되며 다시 CPU 권한을 프로세스A에게 넘겨주게 된다.&lt;br&gt;이럴 경우 Context Switch가 발생한 것이 아닌 단순히 Mode가 변환된 것이다.(User Mode -&amp;gt; Kernel Mode -&amp;gt; User Mode)&lt;br&gt;그렇지만 프로세스A의 코드를 실행하다가 커널의 코드를 실행하기 때문에 아주 약간의 Context는 PCB에 저장하고 있어야 한다.&lt;br&gt;Context Switch는 위와 같은 경우보다 더 많은 Overhead가 발생하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;그러나 프로세스A에서 Timer Interrupt나 I/O 요청 Interrupt를 발생하게 되면 커널에게 CPU 권한이 넘어가게 되고 다시 프로세스B에게 권한을 넘겨주게 되면 Context Switch가 발생하게 된 것이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;5. 프로세스를 스케줄링하기 위한 큐&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eChTWq/btqYZ6mSFop/QmKzTwjKO24ArsDbHJYn4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eChTWq/btqYZ6mSFop/QmKzTwjKO24ArsDbHJYn4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eChTWq/btqYZ6mSFop/QmKzTwjKO24ArsDbHJYn4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeChTWq%2FbtqYZ6mSFop%2FQmKzTwjKO24ArsDbHJYn4k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Ready Queue와 Device Queue는 Job Queue에 포함된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cj2XAJ/btqYTNakZR1/kK2yMkOrDkZAadTErNYgQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cj2XAJ/btqYTNakZR1/kK2yMkOrDkZAadTErNYgQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cj2XAJ/btqYTNakZR1/kK2yMkOrDkZAadTErNYgQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcj2XAJ%2FbtqYTNakZR1%2FkK2yMkOrDkZAadTErNYgQ0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Queue에 줄 서있는 것은 프로세스가 아닌 PCB이다.&lt;br&gt;PCB에는 포인터가 있어 포인터를 활용하여 줄을 서있게 된다.&lt;em&gt;(3. PCB 참고)&lt;/em&gt;&lt;br&gt;Queue는 운영체제가 관리를 하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;6. 스케줄러&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d6CZXh/btqYZ7zjNql/npqJRX8KHabZAJ2skhkrIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d6CZXh/btqYZ7zjNql/npqJRX8KHabZAJ2skhkrIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d6CZXh/btqYZ7zjNql/npqJRX8KHabZAJ2skhkrIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd6CZXh%2FbtqYZ7zjNql%2FnpqJRX8KHabZAJ2skhkrIk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;strong&gt;Long-term Scheduler&lt;/strong&gt;는 어떤 프로세스가 New 상태에 있을 때 해당 프로세스에게 메모리를 주어 Ready로 넘길지 말지를 결정하는 것이다.&lt;br&gt;&lt;strong&gt;Degree of Multiprogramming&lt;/strong&gt;은 메모리에 올라가 있는 프로세스의 수를 뜻한다.&lt;br&gt;Degree of Multiprogramming이 너무 많아도, 적어도 컴퓨터 성능은 떨어진다.(효율성이 중요하다.)&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;보통 시스템에서는 Long-term Scheduler는 거의 없다.&lt;br&gt;Long-term Scheduler 대신 Medium-Term Scheduler를 사용한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Medium-Term Scheduler&lt;/strong&gt;는 일단 메모리에 프로세스를 전부 올려놓고 너무 많이 올라가 있을 경우 Disk로 쫓아낸다.&lt;br&gt;Long-term Scheduler는 메모리를 주는 것, Medium-Term Scheduler는 메모리를 뺏는 것이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Short-term Scheduler&lt;/strong&gt;는 다음번에 어떤 프로세스에게 CPU 권한을 줄지 결정하는 것으로 CPU Scheduler로 불리기도 한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;7. 프로세스의 상태(Porcess State) - Suspended 추가&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qCScF/btqYZ68fJ7Z/lLUJAHkCKdu7iXce6VWLyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qCScF/btqYZ68fJ7Z/lLUJAHkCKdu7iXce6VWLyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qCScF/btqYZ68fJ7Z/lLUJAHkCKdu7iXce6VWLyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqCScF%2FbtqYZ68fJ7Z%2FlLUJAHkCKdu7iXce6VWLyK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Suspended는 Medium-Term Scheduler에 의해 메모리르 통째로 빼앗긴 상태이다.(Disk에 Swap out된 상태)&lt;br&gt;Blocked는 자신의 요청한 일을 하면서 기다리는 상태이다.(Event가 만족되면 다시 Ready상태로 바뀜)&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Suspended는 외부에서 정지해놓은 상태이며 외부에서 Resume해주어야 Active한 상태로 넘어갈 수 있다.&lt;br&gt;Medium-Term Scheduler 뿐만 아니라 외부에 의한 정지로 인해 Suspended가 될 수 있다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;8. 프로세스 상태도 - Suspended 추가&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MK6pU/btqYN2FWBB8/uyqFWkXGk263d07sCJXAKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MK6pU/btqYN2FWBB8/uyqFWkXGk263d07sCJXAKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MK6pU/btqYN2FWBB8/uyqFWkXGk263d07sCJXAKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMK6pU%2FbtqYN2FWBB8%2FuyqFWkXGk263d07sCJXAKk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Running(User Mode)는 프로세스가 CPU 권한을 가지고 있으면서 User Mode로 실행중인 상태이다.&lt;br&gt;Running(Monitor Mode)는 프로세스가 Kernel Mode에서 Running하고 있는 상태이다.&lt;br&gt;프로세스 상태에 대한 용어(Running, Ready등)는 CPU 입장에서의 용어이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Blocked 상태에서 Suspended된 것(Swap out)을 Suspended Blocked라고 하며&lt;br&gt;Ready 상태에서 Suspenede된 것(Swap out)을 Suspended Ready라고 한다.&lt;br&gt;Suspended Blocked는 I/O 요청이 완료되거나 Event가 완료되었을 때 inactive한 상태여도 Suspended Ready로 바뀔 수 있다.&lt;/p&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/7</guid>
      <comments>https://immigrationssu.tistory.com/entry/4-Process-1#entry7comment</comments>
      <pubDate>Sat, 27 Feb 2021 21:22:07 +0900</pubDate>
    </item>
    <item>
      <title>3. System Structure &amp;amp; Program Execution 2</title>
      <link>https://immigrationssu.tistory.com/entry/3-System-Structure-Program-Execution-2</link>
      <description>&lt;blockquote&gt;
&lt;h1&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;/h1&gt;
&lt;p&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=3dd1117c48123b8e&quot;&gt;http://www.kocw.net/home/cview.do?lid=3dd1117c48123b8e&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. 동기식 입출력과 비동기식 입출력&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ehic9p/btqYJ8MzYMB/p1YUEY8FuBQBD5PvA1TqJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ehic9p/btqYJ8MzYMB/p1YUEY8FuBQBD5PvA1TqJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ehic9p/btqYJ8MzYMB/p1YUEY8FuBQBD5PvA1TqJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fehic9p%2FbtqYJ8MzYMB%2Fp1YUEY8FuBQBD5PvA1TqJK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5B0Yc/btqYB45w8xv/1dwJy3eCAfxI1C3kkzL4V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5B0Yc/btqYB45w8xv/1dwJy3eCAfxI1C3kkzL4V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5B0Yc/btqYB45w8xv/1dwJy3eCAfxI1C3kkzL4V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5B0Yc%2FbtqYB45w8xv%2F1dwJy3eCAfxI1C3kkzL4V0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;동기식 입출력은 I/O Device까지 가서 어떤 일을 하는 지 보고 결과를 가져와서 다음일을 하는 것이다.&lt;br&gt;동기식 입출력의 구현방법은 2가지다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I/O가 끝날 때 까지 CPU 소유권을 가지고 기다리는 것&lt;/li&gt;
&lt;li&gt;CPU 소유권을 빼앗기고 I/O가 끝날 때 까지 block 상태로 있는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;비동기식 입출력은 I/O Device의 일을 기다리지 않고 다음 일을 하는 것이다.&lt;/p&gt;
&lt;p&gt;Input은 보통 동기식이며 Output은 비동기식으로 동작한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. DMA Controller&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NaiIx/btqYIjOqzZk/kSd9Jij5tr7ol3eitClAVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NaiIx/btqYIjOqzZk/kSd9Jij5tr7ol3eitClAVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NaiIx/btqYIjOqzZk/kSd9Jij5tr7ol3eitClAVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNaiIx%2FbtqYIjOqzZk%2FkSd9Jij5tr7ol3eitClAVk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;I/O Device로 인해 CPU가 Interrupt에 걸리는 횟수가 너무나도 많아지게 되며 결국 효율적인 동작을 하지 못하게 된다.&lt;br&gt;이것을 예방하기 위해 DMA Controller가 존재한다.&lt;br&gt;DMA Controller는 CPU와 동일하게 직접 메모리에 접근할 수 있는 Controller이다.&lt;br&gt;CPU와 DMA가 동일한 영역의 메모리를 접근할 수 있는 일이 발생할 수 있다.&lt;br&gt;그래서 Memory Controlle가 접근 순서를 정하여 예방해주는 역할을 한다.  &lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;위에서도 언급했다시피 CPU가 직접 I/O Device의 잦은 Interrupt 동작을 수행하는 것은 너무 비효율적이기 때문에&lt;br&gt;I/O Device가 CPU가 아닌 DMA에게 Interrupt를 요청하고 해당 I/O Device의 Local Buffer작업이 완료되면&lt;br&gt;DMA가 직접 I/O Device Local Buffer에 내용을 해당 프로그램 메모리 영역에 Copy를 해준 후 CPU에게 작업완료 Interrupt만 요청하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;위 그림에서 Controller가 DMA이다.&lt;br&gt;I/O의 작은 일들은 특정 블록만큼 데이터가 쌓이면 CPU에게 Interrupt를 요청한다.&lt;br&gt;&lt;code&gt;사용자가 키보드 하나 쳤다고 바로 CPU에 Interrupt를 걸면 CPU가 일을 못하게 된다.&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Device에서 메모리에 직접 Copy를 하고 그 다음 Interrupt를 한번 걸어서 동작이 완료되는 것을 알린다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3. 서로 다른 입출력 명령어&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8tevd/btqYJ9kpY87/k4rui4Ecs9Spi0kpMHwMAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8tevd/btqYJ9kpY87/k4rui4Ecs9Spi0kpMHwMAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8tevd/btqYJ9kpY87/k4rui4Ecs9Spi0kpMHwMAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8tevd%2FbtqYJ9kpY87%2Fk4rui4Ecs9Spi0kpMHwMAk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;I/O를 할 수 있는 방법은 크게 2가지가 있다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;좌측에 있는 방식은 메모리에 접근하는 Instruction과 I/O에 접근하는 Instruction이 따로 있게 된다, 이것이 일반적인 I/O 방식이다.&lt;br&gt;우측에 있는 방식은 I/O 장치 또한 메모리 주소의 연장 주소로 메모리 Instruction을 통해서만 사용된다.&lt;br&gt;이것을 Memory Mapped I/O라 한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;4. 저장장치 계층 구조&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVKmC2/btqYE71KPni/donr2WGkNKXtknzb3PefSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVKmC2/btqYE71KPni/donr2WGkNKXtknzb3PefSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVKmC2/btqYE71KPni/donr2WGkNKXtknzb3PefSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVKmC2%2FbtqYE71KPni%2Fdonr2WGkNKXtknzb3PefSK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;위층으로 올라갈수록 속도가 빠르나 단위 공간당 가격이 비싸 용량이 적다.&lt;br&gt;Secondary(HDD, 테이프)는 비휘발성인 반면 Primary(DRAM, 캐시, 레지스터)는 휘발성이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Primary는 CPU에서 직접 접근하는 것이며 Secondary는 CPU가 직접 접근하지 못하는 것이다.&lt;br&gt;CPU는 Byte단위로 접근이 가능해야 한다.&lt;br&gt;HDD는 섹터단위의 접근이 필요하여 CPU가 접근하지 못하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;CPU는 빠르게는 1clock당 instruction을 처리하게 되는데 DRAM은 하나를 처리하는데 많으면 100clock Cycle이 걸리게 되어 매우 오랜 시간이 걸린다.&lt;br&gt;이러한 속도차이를 완충해주는 것이 바로 캐시 메모리이다.&lt;br&gt;캐시 메모리는 메인 메모리보다 용량이 작아 당장 필요한 것만 올려 쓰게 된다.&lt;br&gt;이것을 캐싱이라고 한다.&lt;br&gt;보통 재사용을 목적으로 사용한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;5. 프로그램의 실행&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGzzSK/btqYxqg6UTR/MyHWiJgt0r9doxZslkIB71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGzzSK/btqYxqg6UTR/MyHWiJgt0r9doxZslkIB71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGzzSK/btqYxqg6UTR/MyHWiJgt0r9doxZslkIB71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGzzSK%2FbtqYxqg6UTR%2FMyHWiJgt0r9doxZslkIB71%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;어떠한 프로그램을 실행시키게 되면 그 프로그램의 독자적인 Address Space가 형성된다.&lt;br&gt;Address Space는 Code, Data, Stack으로 구성된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code : 프로그램의 동작 코드&lt;/li&gt;
&lt;li&gt;Data : 변수와 같은 프로그램의 자료구조&lt;/li&gt;
&lt;li&gt;Stack : 코드의 함수를 호출하거나 리턴할 때 데이터를 쌓거나 꺼내가는 용도&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;프로그램이 실행될 때 생기는 Address Space를 바로 물리적인 메모리에 올릴 경우 메모리가 낭비가 된다.&lt;br&gt;실행되는 코드만을 물리적인 메모리에 올리게 된다.&lt;br&gt;나중에 사용이 되지 않으면 다시 메모리에서 쫓아내어 Disk(Swap Area)에 내려놓게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;File System HDD와 Swap area HDD는 다른 역할을 하게 된다.&lt;br&gt;File System은 비휘발성이며 Swap area는 휘발성이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Address Space의 주소와 물리적 메모리의 주소는 다르게 된다.&lt;br&gt;이것을 Address translation(주소 변환)이라고 한다.&lt;br&gt;Address translation은 커널이 하는 것이 아니며 H/W의 도움을 받게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;6. 커널 주소 공간의 내용&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oPVJp/btqYAt5FmBT/ef6KHcAudT33NSn7kChSK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oPVJp/btqYAt5FmBT/ef6KHcAudT33NSn7kChSK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oPVJp/btqYAt5FmBT/ef6KHcAudT33NSn7kChSK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoPVJp%2FbtqYAt5FmBT%2Fef6KHcAudT33NSn7kChSK0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;커널 또한 일종의 프로그램이다.&lt;br&gt;그렇기 때문에 커널의 주소공간 또한 Code, Data, Stack으로 구성되어 있다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;코드에는 자원을 관리하는 코드, 시스템 콜, ISR등등의 코드로 구성되어 있다.&lt;br&gt;Data에는 H/W의 자료구조와 프로그램을 관리하기 위한 자료구조인 PCB등으로 구성되어 있다.&lt;br&gt;운영체제 또한 함수구조로 코드가 짜여있어 Stack 영역을 사용해야 한다.&lt;br&gt;여러 사용자 프로그램이 커널의 코드를 쓰기 때문에 커널의 Stack은 사용자 프로그램별로 구성되어 있다.&lt;/p&gt;
&lt;h1&gt;7. 사용자 프로그램이 사용하는 함수&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCW2wp/btqYQxY8SVF/RGkULpkfb2IOBbK05PEu51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCW2wp/btqYQxY8SVF/RGkULpkfb2IOBbK05PEu51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCW2wp/btqYQxY8SVF/RGkULpkfb2IOBbK05PEu51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCW2wp%2FbtqYQxY8SVF%2FRGkULpkfb2IOBbK05PEu51%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;모든 프로그램은 함수구조로 코드가 짜여져 있다.&lt;br&gt;사용자 정의 함수와 라이브러리 함수 모두 컴파일 해서 실행파일을 만들면 해당 실행파일 안에 함수가 포함되어 있다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;커널 함수는 사용자 프로그램이 아닌 커널 코드안에 들어 있는 함수이며 사용자 프로그램에서는 호출만 할 수 있다.&lt;br&gt;커널의 함수는 시스템 콜을 통해서만 사용할 수 있다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;사용자 프로그램의 Address Space와 커널의 Address Space는 영역자체가 다르기 때문에 점프가 불가능 하다.&lt;br&gt;점프라는 것은 물리적인 메모리가 아닌 프로그램의 논리적인 메모리(가상 메모리)에서 주소를 옮기는 것을 뜻한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBkjkj/btqYIjniXNx/kLyMpJE5h17oMRVDwMYVqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBkjkj/btqYIjniXNx/kLyMpJE5h17oMRVDwMYVqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBkjkj/btqYIjniXNx/kLyMpJE5h17oMRVDwMYVqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBkjkj%2FbtqYIjniXNx%2FkLyMpJE5h17oMRVDwMYVqk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User Mode : 사용자 프로그램이 CPU를 가지고 있는 것&lt;/li&gt;
&lt;li&gt;Kernel Mode : OS(커널)가 CPU를 가지고 있는 것&lt;br&gt;프로그램은 User Mode와 kernel Mode를 반복하다 종료되는 것이다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/4</guid>
      <comments>https://immigrationssu.tistory.com/entry/3-System-Structure-Program-Execution-2#entry4comment</comments>
      <pubDate>Thu, 11 Feb 2021 19:39:48 +0900</pubDate>
    </item>
    <item>
      <title>2. System Structure &amp;amp; Program Execution 1</title>
      <link>https://immigrationssu.tistory.com/entry/2-System-Structure-Program-Execution-1</link>
      <description>&lt;blockquote&gt;
&lt;h1&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;/h1&gt;
&lt;p&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=36f314da6dc42576&quot;&gt;http://www.kocw.net/home/cview.do?lid=36f314da6dc42576&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. 컴퓨터 시스템 구조&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxYkIC/btqW1sFuEWe/K77yMp4n0l1UsmDtUa2itK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxYkIC/btqW1sFuEWe/K77yMp4n0l1UsmDtUa2itK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxYkIC/btqW1sFuEWe/K77yMp4n0l1UsmDtUa2itK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxYkIC%2FbtqW1sFuEWe%2FK77yMp4n0l1UsmDtUa2itK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;CPU의 작업공간은 메모리이며 Clock Cycle마다 메모리에서 기계어를 하나씩 읽어서 실행하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Device는 &lt;strong&gt;Device Controller&lt;/strong&gt;에 의해 제어된다.&lt;br&gt;Devcie Controller는 일종의 작은 CPU역할을 하게 되는 것이다.&lt;br&gt;Device Controller 또한 작업공간이 필요하며 그것을 &lt;strong&gt;Local Buffer&lt;/strong&gt;라 칭한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;CPU는 메모리에서 instruction(명령어)를 읽어서 실행하게 된다.&lt;br&gt;CPU안에는 메모리보다 빠르고 정보를 저장할 수 있는 Regiter가 존재한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Mode bit는 CPU를 사용하는 것이 운영체제(커널)인지 사용자 프로그램인지 구분할 수 있게 해주는 bit이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Interrupt line은 I/O Device에서 요청되는 것을 캐치하는 것이다.&lt;br&gt;I/O Devcie에서 어떠한 요청이 오게되면 CPU는 Device Controller에게 해당 요청을 처리하게 한다.&lt;br&gt;Device Controller는 Local buffer에 처리된 결과를 저장해놓는다.&lt;br&gt;CPU는 처리된 결과 값을 가져와서 다음 동작을 하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;무한 루프 프로그램이 실행 될때는 CPU가 제대로 된 시분할 동작을 하지 못하게 된다.&lt;br&gt;이것을 방지하기 위해서 &lt;strong&gt;Timer&lt;/strong&gt;가 존재한다.&lt;br&gt;Timer는 Interrupt를 통해서 CPU에게 알려주게 된다.&lt;br&gt;&lt;strong&gt;CPU는 1가지의 instruction을 완료하면 Interrupt line을 확인한 후 Interrupt가 없을 시 다음 instruction을 수행한다.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;운영체제가 사용자 프로그램의 CPU 소유권을 관리하며 사용자 프로그램은 보안적인 문제 때문에 직접 I/O Device에 접근할 수 없다.&lt;br&gt;I/O Device에 접근할 수 있는 모든 instruction은 운영체제를 통해서만 접근할 수 있게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;예를 들어 &amp;#39;사용자 프로그램A&amp;#39;에서 I/O Device의 값이 필요하게 되면 해당 Device Controller에게 동작을 요청한다.
Device Controller가 동작이 완료된 후 자신의 Local Buffer에 결과 값을 넣게 되면 CPU에게 Interrupt를 걸게 된다.
CPU는 interrupt가 오게 되면 진행중이던 다른 &amp;#39;사용자 프로그램B&amp;#39;를 중단하고 운영체제에게 CPU 소유권을 넘기게 된다.
운영체제는 Interrupt 요청을 확인하고 해당 Local buffer 값을 해당 동작을 요청한 &amp;#39;사용자 프로그램A&amp;#39; 메모리에 Copy한다.
이후 interrupt로 인해 중단된 &amp;#39;사용자 프로그램B&amp;#39;에게 timer 시간이 남아있을 때까지 CPU소유권을 넘겨주게 되면서
I/O Device 값이 필요했던 &amp;#39;사용자 프로그램A&amp;#39;에게도 차례가 되면 CPU 소유권을 주게 된다.&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. Mode bit&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AzOSO/btqWVRTRflA/f0d1TxW0rDw9UTIgDjCIu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AzOSO/btqWVRTRflA/f0d1TxW0rDw9UTIgDjCIu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AzOSO/btqWVRTRflA/f0d1TxW0rDw9UTIgDjCIu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAzOSO%2FbtqWVRTRflA%2Ff0d1TxW0rDw9UTIgDjCIu0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;Mode bit가 0일 때(OS가 CPU를 가지고 있을 때)는 모든 Instruction을 사용할 수 있다.&lt;br&gt;-&amp;gt; 메모리 영역, I/O Device등등..&lt;br/&gt;&lt;br/&gt;&lt;br&gt;Mode bit가 1일 때(사용파 프로그램이 CPU를 가지고 있을 때)는 보안문제 때문에 제한적인 Instruction만 수행하게 되어 있다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;운영체제가 사용자 프로그램에게 CPU 소유권을 넘겨줄 때는 Mode bit를 1로 변경한 후 넘겨주게 되어있다.&lt;br&gt;Interrupt가 들어오게 되면 CPU 소유권이 운영체제에게 넘어가면서 자동으로 Mode bit가 0으로 변경된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3. Timer&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lSSg4/btqW4hwWaee/HKDbF5jzzHYbkXetLPJZl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lSSg4/btqW4hwWaee/HKDbF5jzzHYbkXetLPJZl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lSSg4/btqW4hwWaee/HKDbF5jzzHYbkXetLPJZl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlSSg4%2FbtqW4hwWaee%2FHKDbF5jzzHYbkXetLPJZl0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;TImer는 특정 사용자 프로그램이 CPU를 독점하는 것을 방지하기 위해 존재한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;4. Device Controller&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JcjA8/btqWU7bBsOm/xFFzMJkEJw6Xa5rjFauyFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JcjA8/btqWU7bBsOm/xFFzMJkEJw6Xa5rjFauyFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JcjA8/btqWU7bBsOm/xFFzMJkEJw6Xa5rjFauyFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJcjA8%2FbtqWU7bBsOm%2FxFFzMJkEJw6Xa5rjFauyFK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;메모리는 원칙적으로 CPU만 접근할 수 있다.&lt;br&gt;CPU는 메모리와 Local Buffer에 접근이 가능하다.&lt;br&gt;Device Controller는 I/O Device의 작업이 끝났을 경우 Interrupt로 CPU에게 그 사실을 알린다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;운영체제 코드 중 각 Device를 접근하기 위한 Device 인터페이스가 존재하게 된다.&lt;br&gt;Device Driver는 해당 Device 인터페이스에 맞게 접근할 수 있게 해주는 S/W 모듈이다.&lt;br&gt;그래서 I/O Device(H/W)를 설치하게 되면 해당 Device에 맞는 Device Driver를 설치해야 한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;예를 들어 메모리의 Instruction 중 I/O Device에 접근을 해야하는 경우가 생긴다면 Device Driver를 통해서 I/O Device의 Device Controller에게 명령을 하게 된다.
예를 들어 Disk에게 명령을 했다고 가정할 때 Device Driver는 Disk에 헤더를 직접 움직이게 하는 코드가 아니라 Disk Controller를 제어하는 코드가 되는 것이다.
CPU 또한 직접 일을 하는 것이 아닌 메모리에 있는 instruction을 통해 지시를 받아 일을 하는 것이다.
Disk Contorller가 실행하는 Device Driver의 instruction 코드는 Disk가 가지고 있는 F/W를 참고하여 실행하게 된다.
Device Driver는 CPU가 실행하는 코드를 담고있다.&lt;/code&gt;&lt;br&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;5. 입출력(I/O)의 수행 &amp;amp; 시스템 콜 &amp;amp; 인터럽트(Interrupt)&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L4mqr/btqW1tj6SDR/JCfQVpyX5jRNksIklzgEd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L4mqr/btqW1tj6SDR/JCfQVpyX5jRNksIklzgEd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L4mqr/btqW1tj6SDR/JCfQVpyX5jRNksIklzgEd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL4mqr%2FbtqW1tj6SDR%2FJCfQVpyX5jRNksIklzgEd1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLjG90/btqWU82ClMS/dZxob9qVgTfaKr92BHzY9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLjG90/btqWU82ClMS/dZxob9qVgTfaKr92BHzY9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLjG90/btqWU82ClMS/dZxob9qVgTfaKr92BHzY9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLjG90%2FbtqWU82ClMS%2FdZxob9qVgTfaKr92BHzY9k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;모든 I/O 관련 명령은 운영체제만이 사용할 수 있는 특권명령이다.&lt;br&gt;사용자 프로그램에서 I/O를 사용할 수 있는 방법은 바로 시스템 콜이다.&lt;br&gt;시스템 콜은 사용자 프로그램이 OS의 서비스를 받기 위해 커널 함수를 호출하는 것이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;시스템 콜은 일반 함수호출과 다른다.&lt;br&gt;사용자 프로그램 안에서의 함수호출은 프로그램안에 메모리 주소를 바꾸면 된다.&lt;br&gt;시스템 콜은 메모리 주소를 바꾼다고 되는 것이 아닌 복잡한 작업이다.&lt;br&gt;프로그램이 운영체제에게 어떤 것을 요구하기 위해서 자발적으로 CPU에게 Interrupt를 요청할 수 있다.&lt;br&gt;운영체제 입장에서는 시스템 콜이 들어왔다고 해서 바로 실행하는 것이 아니라 올바른 명령인지와&lt;br&gt;요청을 걸어온 사용자 프로그램이 해당 권한이 있는지를 확인한 후 실행하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3TqRm/btqWU8InRWE/Bp6p7aPFjXKW3kKY0Fx5Rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3TqRm/btqWU8InRWE/Bp6p7aPFjXKW3kKY0Fx5Rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3TqRm/btqWU8InRWE/Bp6p7aPFjXKW3kKY0Fx5Rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3TqRm%2FbtqWU8InRWE%2FBp6p7aPFjXKW3kKY0Fx5Rk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXVfnS/btqW4iikBqn/XH95zAUhaD1xbLsGBzkKd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXVfnS/btqW4iikBqn/XH95zAUhaD1xbLsGBzkKd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXVfnS/btqW4iikBqn/XH95zAUhaD1xbLsGBzkKd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXVfnS%2FbtqW4iikBqn%2FXH95zAUhaD1xbLsGBzkKd1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CISKV/btqW1tYJwAD/Os1wqqSMoiwRwsW4e3ZWqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CISKV/btqW1tYJwAD/Os1wqqSMoiwRwsW4e3ZWqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CISKV/btqW1tYJwAD/Os1wqqSMoiwRwsW4e3ZWqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCISKV%2FbtqW1tYJwAD%2FOs1wqqSMoiwRwsW4e3ZWqK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br&gt;일반적인 Interrupt의 의미는 H/W가 발생시킨 Interrupt이며 S/W가 발생시킨 Interrupt는 &lt;strong&gt;Trap&lt;/strong&gt;이라 한다.&lt;br&gt;I/O Device를 사용하기 위한 Interrupt는 H/W와 S/W 둘 다 해당하게 된다.&lt;br&gt;&lt;code&gt;I/O 요청은 S/W, I/O 응답은 H/W&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Interrupt 요청이 들어왔을 때 어떤 식으로 대응을 해줄 것인지는 이미 운영체제(커널) 에 함수가 있다.&lt;br&gt;그것을 &lt;strong&gt;Interrupt Service Routine&lt;/strong&gt; or &lt;strong&gt;Interrupt Handler&lt;/strong&gt;라고 한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Interrupt 요청이 들어왔을 때 어떠한 ISR로 가야하는지 표시해주는 것이 &lt;strong&gt;Interrupt Vector&lt;/strong&gt;이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;운영체제는 CPU를 잡을 이유가 없으며 Interrupt가 발생할 시에만 사용하게 된다.&lt;br&gt;CPU는 항상 사용자 프로그램에 의해서만 사용되어야 한다.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Deivce Driver 부분이 이해하는데 어려웠다..&lt;/code&gt;&lt;/p&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/3</guid>
      <comments>https://immigrationssu.tistory.com/entry/2-System-Structure-Program-Execution-1#entry3comment</comments>
      <pubDate>Thu, 11 Feb 2021 19:35:58 +0900</pubDate>
    </item>
    <item>
      <title>1. Introduction to Operating Systems</title>
      <link>https://immigrationssu.tistory.com/entry/1-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
      <description>&lt;blockquote&gt;
&lt;h1&gt;KOCW 반효경 교수님 운영체제 강의 정리&lt;/h1&gt;
&lt;p&gt;이 글은 공부한 것을 복습 및 기록하기 위한 게시물입니다.&lt;br&gt;잘못된 정보가 기입되어 있을 수 있으니 주의해주시기 바랍니다.&lt;br&gt;강의 링크 : &lt;a href=&quot;http://www.kocw.net/home/cview.do?lid=af8e05c97c6d60de&quot;&gt;http://www.kocw.net/home/cview.do?lid=af8e05c97c6d60de&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1. 운영체제란 무엇인가?&lt;/h1&gt;
&lt;p&gt;컴퓨터 하드웨어 바로 위에 설치되어 사용자 및 다른 모든 S/W와 H/W를 연결하는 소프트웨어 계층&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;협의의 운영체제(&lt;strong&gt;커널&lt;/strong&gt;)는 운영체제의 핵심 부분으로 메모리에 상주하는 부분을 얘기한다.&lt;br&gt;광의의 운영체제는 커널뿐 아니라 각종 주변 시스템 유틸리티를 포함한 개념이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;2. 운영체제의 목적&lt;/h1&gt;
&lt;p&gt;운영체제의 목적은 &lt;strong&gt;컴퓨터 시스템의 자원을 효율적으로 관리&lt;/strong&gt;하는데 있다.(자원관리자)&lt;br&gt;-&amp;gt; 프로세서, 기억장치, I/O등의 효율적 관리&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;또한 사용자간의 형평성 있는 자원 분배를 해야한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;운영체제는 H/W 자원(resource)을 효율적으로 관리해주는 것이 가장 중요하다.&lt;br&gt;또 다른 목적으로는 컴퓨터 시스템을 편리하게 사용할 수 있는 환경을 제공해주는 것이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;운영체제는 효율성과 형평성을 모두 고려해야 한다.&lt;br&gt;효율성 - 주어진 자원(resource)으로 최대한의 성능을 내는 것&lt;br&gt;형평성 - 특정 사용자가 차별받는 상황이 생기지 않는 것&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;운영체제는 H/W 자원(resource) 뿐만 아니라 S/W 자원(resource)도 관리해야 한다.&lt;br&gt;사용자는 운영체제 덕분에 H/W 자원(resource)이 어떻게 실행되는지 알 필요가 없다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;CPU는 아주 짧은 시간 간격으로 프로그램을 할당한다.(CPU가 1개일 경우)&lt;br&gt;워낙 빠르게 진행되어 사용자는 동시에 프로그램이 실행되는 것으로 생각할 수 있다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;메모리 또한 각 프로그램에게 메모리를 할당해주어야 한다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h1&gt;3. 운영체제의 분류&lt;/h1&gt;
&lt;p&gt;운영체제는 아래의 3가지 기준으로 분류할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;동시 작업 가능 여부&lt;/li&gt;
&lt;li&gt;사용자의 수&lt;/li&gt;
&lt;li&gt;처리 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3-1.동시 작업 가능 여부에 따른 분류&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;단일 작업(Single Tasking)&lt;br&gt;한번에 하나의 작업만 처리한다.&lt;/li&gt;
&lt;li&gt;다중 작업(Multi Tasking)&lt;br&gt;동시에 두개 이상의 작업을 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;현대의 운영체제는 다중작업을 진행해주는 운영체제이다.&lt;/p&gt;
&lt;h2&gt;3-2. 사용자의 수에 따른 분류&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;단일 사용자(Single User)&lt;br&gt;MS-DOS&lt;/li&gt;
&lt;li&gt;다중 사용자(Multi User)&lt;br&gt;UNIX, NT Server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PC 1대를 여러 사용자가 사용할 수 있는지를 기준으로 정의한다.&lt;br&gt;다중 사용자용일 경우 보안기능이 추가되어야 하며 형평적인 자원관리를 해주어야 한다.&lt;/p&gt;
&lt;h2&gt;3-3. 처리 방식에 따른 분류&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;일괄 처리(Batch Processing)&lt;br&gt;작업 요청의 일정량을 모아서 한꺼번에 처리하는 운영체제이다.&lt;br&gt;사용자가 작업을 했을 때 바로 반응하지 않는다.&lt;br&gt;현대 운영체제에서는 보기 어려운 운영체제이다.&lt;br&gt;ex) 초기 Punch Card 처리 시스템&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;시분할(Time Sharing)&lt;br&gt;여러 작업을 수행할 때 컴퓨터 처리 능력을 일정한 시간 단위로 분할하여 사용하는 운영체제이다.&lt;br&gt;사용자가 입력한 것이 실시간으로 표현되는 느낌을 준다.&lt;br&gt;시분할은 시간에 제약을 두지 않고 사용자 수에 따라 바뀔 수 가 있다.&lt;br&gt;사용자가 느끼기에 빠르게 해주면서 주어진 자원(resource)을 최대한 활용하는 것을 목적으로 둔다.&lt;br&gt;현재 사용하고 있는 운영체제이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;실시간(Realtime OS)&lt;br&gt;정해진 시간 안에 어떠한 일이 반드시 종료됨이 보장되어야 하는 실시간 시스템을 위한 운영체제이다.&lt;br&gt;ex) 미사일 제어, 반도체 장비 등등&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;시분할과 RTOS 모두 interactive하지만 개념적으로 다르다.&lt;br&gt;RTOS는 시간에 제약이 있어 반드시 해당 시간에 동작이 되어야 한다.&lt;br&gt;특수한 목적을 가진 시스템에서 사용된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* 실시간 시스템의 개념 확장
Hard realtime system(경성 실시간 시스템) - 시간에 제약이 지켜지지 않을 시 치명적인 결함이 생기는 시스템
Soft realtime systme(연성 실시간 시스템) - 시간에 제약이 지켜지지 않을 시 이를 지키지 않더라도 치명적이 결함이 생기지 않는 시스템
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;스마트폰 운영체제는 보통 시분할이지만 RTOS가 필요한 부분이 증가되고 있다.&lt;br&gt;ex) 네비게이션, 블랙박스 등등&lt;/p&gt;
&lt;h2&gt;3-4. 용어 정리&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Multitasking - Task가 여러 개 돌아가고 있지만 CPU에서는 1개의 작업만을 하고있는 것&lt;/li&gt;
&lt;li&gt;Multiprogramming - 메모리에 여러 프로그램이 동시에 올가있는 것&lt;/li&gt;
&lt;li&gt;Time sharing - Multitasking과 유사하지만 CPU를 좀 더 강조한 의미&lt;/li&gt;
&lt;li&gt;Multiprocess - 여러 프로그램이 동시에 진행되는 것&lt;/li&gt;
&lt;li&gt;Multiprocessor - 하나의 PC에 CPU가 여러 개 붙어 있는 것을 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;4. 운영체제의 예&lt;/h1&gt;
&lt;h2&gt;4-1. UNIX&lt;/h2&gt;
&lt;p&gt;UNIX는 대형컴퓨터를 위해 만들어진 운영체제이다.&lt;br&gt;Mutitasking을 지원하며 다중 사용자가 이용 가능하다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;초기에는 어셈블리어로 만들어졌다.&lt;br&gt;대부분에 커널 코드는 C언어로 작성되어 있다.&lt;br&gt;초창기에 UNIX 코드는 오픈소스여서 누구나 가져다 쓰기 쉽고 교육용, 설계용으로 좋은 표본이 되었다.&lt;br&gt;대게 개발자가 UNIX 운영체제를 사용하는 것이 수월하였으나 일반 사용자는 사용하기 어려웠다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;UNIX는 C언어를 사용했기 때문에 다른 기계어를 사용하는 PC에도 사용하기 좋아 높은 이식성을 자랑한다.&lt;br&gt;다만 커널이 커지게 되면 메모리의 대부분을 운영체제가 차지하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;현재 UNIX는 오픈소스가 많이 사라졌지만 리눅스는 현재까지도 오픈소스이다.&lt;br&gt;UNIX는 서버용 운영체제이나 리눅스는 서버용 뿐만 아니라 개인용으로도 사용이 가능하다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;안드로이드 커널 또한 리눅스 커널이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;4-2. DOS(Disk Operating System)&lt;/h2&gt;
&lt;p&gt;MS사에서 개발한 단일 사용자, 단일 작업 운영체제이다.&lt;br&gt;주 기억장치가 640KB밖에 되지 않아 메모리 관리 능력의 한계가 있다.&lt;br&gt;초기에 MS에서는 640KB로도 충분하다고 단언을 하였으나 H/W 발전속도가 빨라 DOS는 망해갔다.&lt;/p&gt;
&lt;h2&gt;4-3. MS Windows&lt;/h2&gt;
&lt;p&gt;MS사에서 개발한 다중 작업용 GUI 기반 운영체제로 개인 PC를 위해 만들어진 운영체제이다.&lt;br&gt;UNIX보다 안정적이지 못하나 요즘 Windows는 불안정성이 많이 해소되었다.&lt;/p&gt;
&lt;h1&gt;5. 운영체제의 구조&lt;/h1&gt;
&lt;h2&gt;5-1. CPU 스케줄링&lt;/h2&gt;
&lt;p&gt;어떤 프로그램에 CPU를 할당할 것인지 선정하는 것&lt;br&gt;일반적으로 CPU 권한을 순서대로 할당하는 것이 합리적이라고 생각하나 컴퓨터에서는 꼭 이러한 방법이 합리적이지만은 않다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;CPU 스케줄링을 순차적으로 처리할 때 한 개의 프로그램이 계속 CPU를 잡고 있을 경우&lt;br&gt;무슨 행동을 하더라도 작업이 되지 않게 된다.&lt;br&gt;그래서 시분할을 일반적으로 사용하게 된다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;5-2. 메모리 관리&lt;/h2&gt;
&lt;p&gt;CPU에서 원활하게 동작하게 할만한 메모리를 할당 받고 있어야 한다.&lt;br&gt;무조건 메모리를 N분의 1로 나눈다고 해서 원활하게 동작하는 것은 아니다.&lt;br&gt;메모리 크기는 한정적이여서 메모리가 꽉 찼을 때는 어떠한 프로그램을 Disk로 보낼 것인지를 정해야 한다.&lt;br&gt;보통 CPU에서 재사용률이 떨어지는 것을 Disk로 보내는 것이 일반적이다.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;5-3. 파일 관리&lt;/h2&gt;
&lt;p&gt;조각조각 나눠 저장하는 것이 좋은지, 일괄적으로 저장하는 것이 좋은지 등을 판단한다.&lt;br&gt;Disk는 헤드가 움직이면서 파일을 읽기때문에 메모리와는 다르다.&lt;br&gt;헤드에 가까운 위치에 요청이 있다면 해당 부분에 대해서 먼저 처리를 한다.&lt;br&gt;엘레베이터 시스템과 유사하다.&lt;br&gt;동작이 빠른 CPU 스케줄링과 성격이 다르다.&lt;/p&gt;
&lt;h2&gt;5-4. 입출력 관리(I/O Device)&lt;/h2&gt;
&lt;p&gt;매우 느리다.&lt;br&gt;기본적으로 인터럽트에 기반해서 관리가 된다.&lt;/p&gt;
&lt;h2&gt;5-5. 프로세스 관리&lt;/h2&gt;
&lt;p&gt;프로세스의 생성과 삭제, 자원 할당 및 반환, 프로세스 간 협력&lt;/p&gt;
&lt;h2&gt;5-6. 그 외&lt;/h2&gt;
&lt;p&gt;보호 시스템, 네트워킹, 명령어해석기 등등&lt;/p&gt;</description>
      <category>Computer Science/OS</category>
      <author>eeminsu</author>
      <guid isPermaLink="true">https://immigrationssu.tistory.com/2</guid>
      <comments>https://immigrationssu.tistory.com/entry/1-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80#entry2comment</comments>
      <pubDate>Sat, 6 Feb 2021 21:12:48 +0900</pubDate>
    </item>
  </channel>
</rss>