해결된 질문
작성
·
1.2K
4
CPU를 말할 때 4코어 4스레드, 8코어 8스레드 혹은 하이퍼쓰레딩이 적용된 CPU는 8코어 16스레드 등으로 말하는데
여기서 말하는 스레드가 커널 스레드인거고, 자바에서 생성한 스레드는 유저스레드인걸까요?
그리고 CPU는 프로세스를 처리하는 것인가요? 아니면 프로세스안에 들어있는 각각의 스레드를 붙잡고 처리하는 것인지 궁금합니다.
혼자 테스트를 해보니 4코어 머신에서는 동시에 4개의 스레드가 작업되고, 8코어 머신에서는 8개의 스레드가 돌아가더라구요.
이말인즉슨, 8코어 머신에서 동시에 8개의 CPU가 자바 스레드를 처리했다는 것 같은데, 이 부분이 잘 이해가 가지 않아서 질문 남깁니다!
제 컴퓨터에서 돌고있는 프로세스가 최소 수십개는 될것이고, 그중 하나가 JVM일건데, JVM 하나를 모든 CPU가 작업했다는의미로 생각되어서요.
하기 GIF는 8코어 머신에서 멀티스레드 프로그래밍을 했을때의 결과입니다.
그리고 정말 좋은 강의 감사드립니다. 🙇♂️
답변 3
3
계속해서 하드웨어 스레드와 커널 스레드의 차이, 커널 스레드와 유저 스레드의 차이를 이해하지 못하고 있었습니다.
이제 약간 감을 잡은 것 같습니다. (제대로 이해했는지는 잘 모르겠습니다. 😅)
우선 운영체제와 커널의 정확한 차이에 대해 찾아보니, 컴퓨터에 전원이 공급되는 한 항상 메모리에 상주하는 운영체제의 가장 핵심적인 부분을 커널이라고 부르는것 같습니다.
그리고 운영체제도 결국 메모리에 탑재되어 동작하는 하나의 프로세스이기 때문에 내부적으로 여러개의 스레드를 가질 수 있으며, 이 스레드들이 대부분 운영체제 스케쥴러에 의해 직접적으로 스케쥴링되는 스레드로 이해됩니다. (즉, 커널 스레드 혹은 OS 스레드 혹은 네이티브 스레드)
본 강의에서는 하나의 프로세스 내에 여러개의 스레드가 존재할 수 있다하였습니다. 프로세스 속의 스레드들은 최소 1개 이상의 커널 스레드와 0개(사용자 입출력조차 없는 경우) 이상의 유저 스레드로 이루어진 것이구요.
그리고 이 유저 스레드들이 여러개 있다면, 한 개 이상의 커널 스레드에 할당되어 시분할처리를 통해 동시성 프로그래밍을 구현합니다.
그리고 결국엔 하드웨어 스레드가 이 커널 스레드들을 일대일로 붙잡고 실제 연산 등의 처리를 진행하는 것이기 때문에 하드웨어 스레드의 갯수가 바로 동시간대에 병렬처리할 수 있는 최대 갯수가 되는것이구요.
초기에는 여러 user-level-thread를 하나의 kernel-level-thread에 매핑했다고 합니다.
하지만 이 방식은 동시성 모델이 제한적이고 멀티프로세서를 활요하지 못해 사용되지 않습니다.
제가 처음 자바를 공부할 때 보았던 대부분의 내용들이 이와 비슷했기 때문에, 결국 하나의 커널 스레드(최근까지는 이것을 CPU 혹은 프로세서라고 생각하고 있었습니다.)에 의해 여러개의 자바 스레드가 시분할처리가 되는것이면, 하나 이상의 자바 스레드가 blocking됐을 경우 다른 스레드들도 다 함께 blocking 될 것이라고 생각했습니다.
근데 최근에 동시성 프로그래밍을 공부하던 중 다음과 같이 동시간대에 여러개의 스레드가 처리되는것을 보고 제가 기존에 알고있던것이 잘못 알고있던 것이라는 의심이 생겼던 거구요.
인텔 8코어 8스레드 CPU
M1 MAC ARM (8코어)
그런 와중에 자바 최적화라는 책을 읽던 중 다음과 같은 내용도 보았습니다.
그래서 운영체제에 대한 기본기가 너무 부족하다는 생각이 들어 자료를 찾다가 이 강의까지 오게 된 것입니다.
암튼 주저리주저리 잡담이 많았는데, 비전공자에게 최고로 좋은 강의와 친절한 답변에 정말 감사드립니다 🙇♂️🙇♂️
큰 도움을 받았습니다.
새해 복 많이받으십셔!
3
제가 지금 이해한게 맞는지 잘 모르겠네요.
설명을 해보자면,
1. CPU 스펙을 이야기할 때 8코어 16스레드라는 표현에서
8코어는 하드웨어 측면에서 말한것이구, 16스레드는 소프트웨어 측면에서 말한것이 맞을까요?
하드웨어가 너무 좋아져 코어하나에 1스레드로는 CPU 코어의 처리량을 따라가지 못하니 스레드를 두개두는것이구요.
비유를 하자면 컨베이어 벨트가 도는 속도가 너무 빨라 작업자 혼자서는 처리를 못하기 때문에 작업자를 두명두는것으로 이해가 되는 것 같아요.
2. 스레드는 커널에 접근할수 있는(시스템 콜 등을 할 수 있는) 커널 스레드와 그렇지 못한 유저 스레드로 나뉘며 커널 스레드는 CPU 스펙을 말할때 사용하는 8코어 16스레드(<-- 요녀석(OS 스레드?))에 매핑되는 것이구요.
그러니까 커널 스레드는 운영체제가 관리하고있는 CPU의 스레드와 같은 의미로 쓰이는 것 같구, JVM은 프로세스이며 JVM이 생성해낸 스레드(자바 스레드)가 유저 스레드인거같네요.
그리고 이 유저 스레드들이 실제로 어떤 작업을 처리하려면 결국 운영체제 스케쥴링에 의해 프로세서(CPU 스레드, 커널스레드)를 할당받아야 하는 것이구요.
그래서 어찌됐건 한순간에 동시에 돌 수 있는 CPU에 종속적이라 결국 16개가 한계인것이죠?
그림으로 표현하면 대략 아래와 같은..?
최근 자바최적화 라는 책을 보고있는데, 제가 비전공 신입이라 전공지식이 빈약해서 책을 보기가 참 힘들었는데, 정말 이해하기 쉬운 좋은 강의 만들어주셔서 큰 도움 받고 갑니다! 감사합니다. 🙇♂️
아닙니다!
8코어 8스레드나 8코어 16스레드나 모두 하드웨어 스레드를 말하는 겁니다.
8코어 8스레드는 하드웨어적으로 동시에 실행할 수 있는 스레드가 8개란 말이고
8코어 16스레드는 하드웨어적으로 동시에 실행할 수 있는 스레드가 16개란 말입니다 ㅎㅎ
다만 8코어 16스레드처럼 한 코어에 여러 개의 스레드가 있는 건 하이퍼스레딩이라고 부르며 하드웨어적인 기술을 말합니다.
실제로 명령어를 처리하는 부분은 코어이지만 코어 내에서도 스레드가 처리합니다.
처리하는 스레드가 1개에서 2개로 늘어났기 때문에 처리성능이 그만큼 좋아지겠죠?
작업 큐(컨베이어 벨트)에 여러 스레드(화물)가 있으니 작업자를 두 명둔 예는 맞는 설명인 것 같아요!
하지만 컨베이어 벨트가 너무 빨라서 처리를 못하기 보다는 혼자 처리하면 그 만큼 오래걸려서 전부 다 처리하는게 오래걸리기 때문에 두명을 뒀다는 표현이 정확한 것 같습니다 ㅎㅎ
2번 질문은 약간 설명이 길어질 것 같습니다.
위에 질문에 제 답변으로 이 글에 가보면 green thread라는 것이 있습니다.
green thread는 user-level-thread로 OS에서 말하는 kernel-level-thread와 차이가 있습니다.
user-level-thread는 OS에서 지원하지 않고 언어 차원(JVM)에서 지원합니다.
green thread는 싱글코어를 환경을 위해 설계되어서 멀티코어 환경에서는 장점을 발휘하지 못한다고 합니다. green thread글을 찾아보면 green thread를 악으로 여기는 글도 찾아볼 수 있을 정도로 문제가 많았던 것 같습니다. 때문에 JDK 1.2이후로 green thread는 사용되지 않는다고합니다.
초기에는 여러 user-level-thread를 하나의 kernel-level-thread에 매핑했다고 합니다.
하지만 이 방식은 동시성 모델이 제한적이고 멀티프로세서를 활요하지 못해 사용되지 않습니다.
(여러개의 사용자 스레드가 커널 스레드 하나에 매핑된 그림, Many To One Model)
이 문제로 하나의 user-level-thread를 하나의 kernel-level-thread에 매핑했습니다.
이로써 모든 스레드가 커설 스레드를 사용하면서 제대로된 멀티스레딩을 제공했지만 성능이 문제가 있어서 다시 바뀝니다.
(하나의 사용자 스레드가 커널 스레드 하나에 매핑된 그림, One to One)
Many to Many 방식은 One to One에서 발생한 성능문제를 해결한 방식입니다.
현재는 이 방식으로 쓰인다고합니다.
하지만 커널 레벨 스레드를 100개 이상 만들어도 결국 동시에 실행되는 스레드는 CPU의 코어수에 따른 스레드의 수만큼입니다. 8코어 16스레드라면 동시에 16개의 스레드만 실행할 수 있습니다!
제가 참조했던 글들 링크달아 놓겠습니다 ㅎㅎ
- Green Thread
- green thread vs non-green thread
- 한창훈님께 추천드리는 자료(과거 스레드 모델구조가 나와있더군요ㅎㅎ)
한글로된 여러 링크
- 스레드 도대체 무엇이길래
- 유저 레벨 스레드 vs 커널 레벨 스레드
한창훈님의 좋은 질문덕분에 저도 자바의 내부에 대해서 많은 걸 알게된 것 같습니다 ㅎㅎ
좋은 질문 감사합니다!!
3
하이퍼스레딩은 1코어에 여러개의 스레드를 지원하는 기술입니다.
CPU 4코어 4스레드를 표현할 때 스레드는 "하드웨어 스레드"를 말합니다! 마찬가지로 8코어 16스레드는 16개의 하드웨어 스레드가 있다는 말입니다.
실제로 하드웨어 스레드가 동시에 처리할 수 있는 스레드의 수입니다.
만약 4코어 4스레드 컴퓨터가 자바에서 스레드를 100개를 생성했더라도 동시에 실행되는 스레드의 수는 4개가 최대입니다!
자바에서 생성되는 스레드는 저도 검색을 통해 알았습니다 ㅎㅎ
JVM은 여러 개의 커널 스레드를 생성하는데 이 커널 스레드가 여러 개의 유저 스레드를 매핑해서 사용한다고 합니다. 즉 유저가 생성한 스레드는 JVM의 커널 스레드를 통해 실행됩니다!
제가 참조한 글은 이 글입니다.
CPU에있는 스레드(하드웨어 스레드)가 프로세스안에 있는 각각의 스레드를 처리합니다.
프로세스 내부에는 1개 이상의 스레드가 있기때문에 CPU의 스레드(하드웨어 스레드)가 각각 스케줄에따라 처리합니다!
혹시 자바스레드에만 동시에 8개의 CPU가 사용되었나요?
만약 자바에만 동시에 8개의 CPU가 사용되었다면 JVM의 커널 스레드와 관련이 있어보입니다!
JVM이 내부적으로 여러개의 커널 스레드를 생성하는데 아마 8개를 생성하지 않았나 싶네요.
제가 JVM의 지식이 많지 않다보니 확답은 할 수 없을 것 같아요!
부족한 강의인데 칭찬해주셔서 감사합니다! ㅎㅎ
운영체제 공부하신 계기가 확실하시군요?
만약 JVM이 Many to One 모델을 사용했다면 이렇게 동작했을겁니다!ㅎㅎ
아마 처음배웠을 때 교육자료가 오래됐거나.. 업데이트를 하지않아서 생긴 오해인것 같네요.
올려주신 책에서는 One to One 모델을 얘기하는 것 같네요.
단순한 의심에서 이렇게 운영체제를 배우시고 의구심을 해결하는게 정말 대단하신 것 같습니다!
존경합니다 ㅎㅎ
다시한번 강의 좋게 봐주셔서 감사합니다!!