스레드가 가상 메모리 또는 실제 메모리를 사용합니까?


10

프로세스 당 10,000 개의 스레드를 처리하도록 Linux 서버를 최적화하려고했지만 지금은 382 개입니다. 에 따라 이 문서의 다음과 같은 공식은 총 가능한 스레드를 확인하는 데 사용됩니다

number of threads = total virtual memory / (stack size*1024*1024)

이는 스레드가 모든 데이터를 가상 메모리에 저장함을 의미합니다. 그리고 내가 아는 한, 가상 메모리는 RAM 또는 캐시보다 하드 디스크에 저장된 Linux 시스템의 스왑 공간입니다.

그래서 내 질문은 스레드가 하드 디스크를 사용하여 데이터를 처리 / 저장하기 위해 저장하는 것입니다.

그렇다면 성능에 영향을 미치지 않습니까? RAM이나 캐시에 넣어서 성능을 향상시킬 수 있습니까? 어떻게?

그렇지 않은 경우 스레드가 정확히 어떻게 작동합니까?

최신 정보:

쓸모없는 답변 에 따르면 가상 메모리는 다음과 같이 구성된 시스템입니다.

  • 물리 메모리 (RAM)
  • 첨부 한 스왑 파일
  • 실제 메모리에서 가상 주소를 사용할 수 없을 때 가상 주소를 물리적 주소로 변환하고 페이지 결함을 발행하기위한 하드웨어 지원
  • (커널) 소프트웨어 지원 : 요청시 스왑에서 페이지를 가져 와서 해당 페이지 결함을 처리하는 하드웨어에서 사용하는 검색 테이블 관리

따라서 가상 메모리에있는 모든 것은 집합 적으로 RAM (실제 메모리) 및 하드 디스크 (스왑 파일)에 있습니다. 그리고로 제임스 그의 대답에 설명 HDD가 커널에 의해 촬영 대 등 LRU로 algorithims를 사용하여 램에 결정.


2
서버에 10,000 개의 CPU / 코어가 없으면 시간을 낭비하게됩니다.

@JarrodRoberson : 왜 그렇습니까?
dragosrsupercool 2015

3
10,000 개의 스레드는 확장을하기에 좋은 방법이 아닙니다. 서버를 크롤링하게하는 좋은 방법입니다. CPU 당 1 개 이상의 스레드가 있거나 Core가 서버 컨텍스트 전환을 더 빠르게하고 느리게 실행하려고합니다.

특히 "Linux 서버를 최적화하려고합니다"라고 말하면 무엇을 최적화하려고합니까? 처리량이 많은 경우 멀티플렉싱 및 비 블로킹 I / O를 사용하는 CPU 당 하나의 스레드가 더 좋습니다.
쓸모없는

답변:


12

내가 아는 한, 가상 메모리는 Linux 시스템의 스왑 공간입니다.

아니요, 가상 메모리는 다음과 같이 구성된 시스템입니다.

  • 물리 메모리 (RAM)
  • 첨부 한 스왑 파일
  • 실제 메모리에서 가상 주소를 사용할 수 없을 때 가상 주소를 물리적 주소로 변환하고 페이지 결함을 발행하기위한 하드웨어 지원
  • (커널) 소프트웨어 지원 :
    • 해당 하드웨어에서 사용하는 검색 테이블 관리
    • 주문형 스왑에서 페이지를 가져 와서 해당 페이지 결함 처리

자신의 사용자 공간 VM 계층 (예 : 데이터베이스, iiuc)을 작성하지 않는 한 원하는 가상 메모리가 RAM에 캐시되도록하는 것은 커널에 달려 있습니다. 걱정하지 마십시오.


내 가상 메모리 가정이 잘못되었습니다. 어쨌든 빠른 후속 질문. SWAP 공간이 RAM보다 큰 경우 완전히로드 된 최대 스레드 성능에 영향을 줍니까?
dragosrsupercool 2013

@dragosrsupercool : 스왑 공간은 항상 실제 메모리보다 클 것입니다. 그렇지 않으면 가상 메모리를 사용해야합니다.
Bryan Oakley

1
@BryanOakley : 반드시 그런 것은 아닙니다. 일부 OS는 할당 된 모든 가상 페이지에 대해 스왑 페이지를 할당합니다 (즉, 스왑은 물리적 크기 이상이어야 함). 다른 OS는 페이지를 실제 메모리 밖으로 이동해야 할 경우에만 스왑 페이지를 할당합니다 (즉, 스왑이 실제보다 작을 수 있음). 전자의 장점은 할당이 성공하면 메모리 교체가 항상 성공한다는 것입니다. 후자의 장점은 비교적 드문 상황을 설명하기 위해 거대한 스왑 파일을 비관적으로 할당 할 필요가 없다는 것입니다.
mcmcc

1
@dragosrsupercool, RAM 이 적고 실제로 페이징 하지 않는 한 RAM의 양, 스왑 또는 그 비율에 따라 성능에 영향을 미치지 않습니다 . sar은 페이징 활동 iirc에 대해 알려줄 수 있습니다 ( sar -BLinux에서 확인 됨 ).
쓸모없는

@Useless : RAM을 완전히 사용하고 페이징을 시작하지 않을 때까지 스레드 수를 늘리고 싶습니다.
dragosrsupercool 2016

14

스레드가 실제로 실행 중이면 현재 명령어 및 스레드가 사용하는 모든 변수가 실제 메모리에 있어야합니다.

대부분의 (실제로 거의 모든) 프로그램은 가상 메모리에 상주하며 대부분의 프로그램은 변수 저장을 위해 가상 메모리를 사용합니다.

페이지라고하는 청크로 구성된 가상 주소 (일반적으로 4096 또는 8192 바이트 블록).

주어진 시간에 가상 메모리의 각 블록은 실제 메모리 또는이를 위해 예약 된 "스왑 공간"의 디스크에 저장됩니다.

프로그램 코드는 가상 주소를 처리 할 때 가상 주소를 처리하거나 시스템 (일반적으로 하드웨어 수준)에서 가상 주소의 저장소에 대한 액세스를 요청하여 주소 요청의 현재 위치를 찾아 가상 주소에 매핑합니다. 주소가 현재 디스크에있는 경우 실제 메모리로 페이징 한 다음 주소를 매핑합니다.

무언가가 페이징 된 경우 모든 물리적 메모리가 사용 중일 때 다른 것이 페이징 아웃되어야하므로 시스템은 "최근 사용 시간"페이지를 찾아 요청한 페이지를 복사하기 전에이를 디스크에 복사합니다.

최신 시스템에는 가상 스토리지와 관련된 여러 가지 최적화 및 트릭이 있습니다.

  • 주소는 "프로세스 당"기준으로 매핑되므로 Linux 상자의 모든 C 프로그램은 동일한 주소에서 "메인"프로세스를 시작합니다.
  • 이는 32 비트 가상 주소가 실제 64 비트 주소에 맵핑 될 수 있으므로 여러 32 비트 프로세스가 점유하고 시스템에서 4GB 이상을 사용할 수있게합니다.
  • 프로세스가 종료되거나 메모리가 "사용 가능"하게되면 시스템은 페이지를 사용 가능으로 표시하고 스왑 디스크로 다시 복사되지 않습니다.
  • 마찬가지로 새로운 스토리지 블록이 요청되면 시스템은 실제 메모리에서 사용 가능한 페이지를 가져옵니다. 디스크 IO가 발생하지 않습니다.
  • 휴면 및 최대 절전 기능은 모든 메모리가 스왑 공간에 복사되도록하여 모든 현재 프로세스 및 현재 메모리 내용을 깨우면 다시 만들 수 있도록합니다.

3
"리눅스 박스에있는 모든 C 프로그램은 같은 주소에서 시작합니다"는 주소 공간 레이아웃 무작위 화를 고려하지 않은 것 같습니다. 오늘날 다양한 스택 스매싱 공격 체계를 막기 위해 점점 더 많이 사용되고 있습니다. 그렇지 않으면 좋은 대답이므로 +1하십시오.
CVn

7

우선, 해당 분야에 대한 지식이 부족하기 때문에 컴퓨터 메모리 에 대한 자세한 내용을 읽어보십시오 .

실행 스레드 는 운영 체제에서 예약 할 수있는 가장 작은 처리 단위입니다. 스레드와 프로세스의 구현은 운영 체제마다 다르지만 대부분의 경우 스레드는 프로세스 내에 포함됩니다. 동일한 프로세스 내에 여러 스레드가 존재할 수 있으며 메모리와 같은 리소스를 공유 할 수 있지만 다른 프로세스는 이러한 리소스를 공유하지 않습니다.

따라서 스레드는 사용 가능한 메모리를 사용합니다. 시작할 수있는 스레드 수는 메모리 크기와 스레드 당 필요한 메모리 양에 따라 다릅니다. 스레드가 힙을 사용하는 경우 (스택뿐만 아니라) 더 많은 메모리가 필요하며이 경우 더 적은 스레드를 시작할 수 있습니다.


@VJonvic : 기본 스레드 설명은 +1입니다.
dragosrsupercool 2013

6

귀하의 질문에 대한 간단한 대답은 가상 메모리를 사용한다는 것입니다. OS와 관련된 소수의 프로세스를 제외하고 모든 것이 가상 메모리를 사용합니다.

반면에 스레드 (또는 프로세스에서 스레드)가 실제로 실행 중이면 실제 메모리를 사용하는 것입니다. 해당 프로세스와 관련된 메모리 페이지는 프로세서가 작동하는 실제 메모리로 교체됩니다.


3

가상 메모리는 RAM 스왑 공간입니다. 가상은 프로그램이 보는 주소가 RAM 칩이 보는 주소와 다르다는 것을 의미합니다. 스왑으로 메모리에 액세스해야하는 경우 OS는 먼저 메모리를 RAM으로 옮깁니다. 스와핑을 원하지 않으면 비활성화하십시오. 충분한 RAM이 있으면 실제로 필요하지 않습니다.

즉, 코어 프로세서가 10,000 개가 아니라면 스레드를 10,000 개로 늘리는 것은 실제로 "최적화"가 아닙니다. 모든 코어를 소비하기에 충분한 스레드와 그 스레드가 차단 될 때를위한 여분의 스레드가 있으면 스레드를 더 추가 하면 스위칭 오버 헤드 및 캐시 누락으로 인해 성능이 저하 됩니다. 프로그램 로직을 단순하게 만들면 더 많은 스레드를 사용하고 싶을 수 있지만 성능을 떨어 뜨릴 수 있습니다.


예, 서버가 32 비트 단일 코어 시스템이므로 10,000이 너무 많습니다. 실제로 스레드는 총 CPU가 아닙니다. 크롤러 스레드이므로 서버 응답을 기다리는 것과 같습니다. CPU가 완전히 점유되었지만 과부하 또는 과부하가 걸리지 않도록하는 것을 목표로합니다. 그러나 여전히 CPU가 비어 있거나 완전히 점유되어 있는지 어떻게 알 수 있습니까? 도구 나 명령이 있습니까?
dragosrsupercool 2016

top명령 에서 정보를 얻을 수 있다고 생각합니다 .
Karl Bielefeldt

@KarlBieledeldt : 그렇습니다. 정확히 내가 찾던 것이 었습니다. 하나의 후속 질문 : 방금 하나의 스레드가 URL에 대한 요청을 보낼 수 있고 다른 스레드가 서버 응답을 수신하는 경우 크롤링에 대한 아이디어를 얻었습니다. 너무 많은 스레드를 사용하지 않고 CPU 사용률이 높습니다. 가능합니까? 다른 스레드에서 응답을받는 동안 한 스레드에서 요청을 보내는 것처럼?
dragosrsupercool 2019

2

프로세스 당 10,000 개의 스레드를 처리하도록 Linux 서버 최적화

다른 사람들이 설명했듯이 이것은 일반적으로 잘못되었습니다. 스레드는 비용이 많이 드는 자원 은 자신이 특히 때문에, 호출 스택 (일반적으로 메가 바이트)를하고 커널 작업 스케줄이기 때문이다. 스레드는 열린 파일 디스크립터 보다 훨씬 비쌉니다 .

운영 체제 : 세 가지 쉬운 자료 (무료로 다운로드 할 수있는 교재)를 읽으십시오 .

일반적으로 스레드가 많지 않고 실행 가능한 스레드가 많지 않기를 원합니다. 실행 가능한 스레드의 수는 일반적으로 최대 수의 코어 (또는 그 수의 작은 배수) 여야 하므로 최대 약 12 ​​개입니다. 프로세스의 스레드 수는 약간 더 클 수 있습니다. 따라서 프로세서 소켓과 코어가 많은 매우 광범위한 서버가 없다면 프로세스에서 (데스크탑) 프로세스에 12 개 이상의 실행 가능한 스레드와 100 개의 스레드 (대부분 유휴 상태)를 원하지 않습니다. .

Linux에서 스레드와 프로세스는 매우 유사합니다 (둘 다 clone (2)에 의해 생성 될 수 있음 ). 그리고 둘 다 커널에 의해 예약 된 작업입니다. 실제로 커널 스케줄러는 일부 멀티 스레드 프로세스 내부의 스레드 또는 단일 스레드 프로세스의 단일 주 스레드 (이 경우 단일 프로세스의 이름을 "프로세스") 또는 커널 스레드 일 수있는 작업을 예약합니다. 데스크탑 시스템에서 총 천 개 이상의 예약 가능한 작업을 원하지 않을 것입니다.

Linux에서 프로세스 는 단순히 동일한 가상 주소 공간 을 공유하고 파일 디스크립터 테이블 등과 같은 다른 것들을 공유하는 스레드 그룹입니다 . 일부 프로세스에는 스레드가 하나만 있습니다.

가상 주소 공간이 되어 정의 로 위키 백과에 의해

"운영 체제에서 프로세스에 사용 가능한 가상 주소 범위 세트"

(또한 볼 이 대답 용어가 보편적 아니라고 설명을하고, 일부 Microsoft 설명서는 사용하는 다른호환되지 않는 정의).

Linux에서 proc (5) 는 일부 프로세스의 가상 주소 공간을 이해하는 데 유용합니다. 터미널
cat /proc/self/mapscat /proc/$$/maps터미널에서 모두 시도하십시오 . 참조 , 그리고 에서 pmap (1)PS (1)최고 (1) .

모든 사용자 공간 프로그램은 일부 프로세스에서 실행되고 가상 메모리를 사용 하므로 모든 프로세스에는 고유 한 가상 주소 공간이 있습니다. 물리적 RAM 은 Linux 커널에서 관리하는 리소스이며 응용 프로그램은 RAM에 직접 액세스 할 수 없습니다 ( mmap (2) -ing 제외 /dev/mem, mem (4) 참조 ).

따라서 프로세스는 직접 RAM을 사용하지 않습니다 . 가상 메모리를 사용하며 자체 가상 주소 공간이 있습니다. 커널은 사용합니다 페이징 물리적 RAM의 관리 페이지를 가상 주소 공간 및 프로세스 제공하는 추상화를 . 프로세스가 유휴 상태이거나 실행중인 경우에도 커널은 일부 페이지를 페이지 아웃 할 수 있습니다 (예 : 디스크에서 스왑). 커널은 MMU를 구성하고 있습니다 (그리고 디스크에서 페이지를 가져 오거나 세그먼트 오류 를 프로세스 로 전파하여 일부 인터럽트 핸들러 에서 페이지 누락 하드웨어 예외 처리, signal (7) 참조 ).

시스템 스레드 위에 녹색 스레드 가있을 수 있지만 녹색 스레드 라이브러리는 구현 및 디버그하기가 어렵습니다. Go 에서 사용 된 루틴을 살펴보고 멋진 예를 들어보십시오. setcontext (3) 도 참조하십시오 .

때때로 시스템이 스 래싱을 실험 할 수 있습니다 . 이것은 모든 프로세스에 필요한 총 가상 메모리가 사용 가능한 실제 RAM을 크게 초과 할 때 발생합니다. 그런 다음 컴퓨터가 응답하지 않게됩니다. 상주 세트 크기 , 요구 페이징 , 작업 세트 , 메모리 초과 확약 , ASLR 에 대해 읽으십시오 .

-for Linux- fork (2) , clone (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , credentials (7) , pthreads (7) 참조 , futex (7) , capability (7) .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.