궁극적으로 최종 사용자 웹 경험을 제공하는 고성능 대용량 데이터 엔진에서 성능 튜닝을하고 있습니다. 구체적으로 말하자면, 나에게 위임 한 자료는 멀티 스레드 파일 IO 및 데이터를 로컬 캐시에 메모리 매핑하는 것과 관련이 있습니다. 타이밍 폴을 분리하기 위해 테스트 애플리케이션을 작성하는 과정에서 몇 가지 질문이 제기되었습니다. 시스템 파일 열기 (open(O_RDONLY)
) 호출 만 수행하도록 코드가 최소화되었습니다. 이 쿼리의 결과로 기본적인 저수준 시스템 프로세스를 이해하고 완전한 예측 (또는 최소한 관계형) 타이밍 모델을 이해하는 데 도움이되기를 바랍니다. 제안은 언제나 환영합니다. 우리는 타이밍 장벽에 부딪 혔으며 행동을 이해하고 그 장벽이 깨질 수 있는지 판단하려고합니다.File open()에 대한 Linux 멀티 스레드 성능 향상
테스트 프로그램 아래에 명시된 바와 같이
- 은 GNU C 컴파일러를 이용하여 컴파일 된 C에 기록된다;
- 발견 된 문제를 단일 시스템 파일 "open()"로 분리하기 위해 최소한으로 작성되었습니다.
- 요청 된 수의 pthread를 동시에 실행하도록 구성 할 수 있습니다.
- ~ 8K 크기의 1000 개의 텍스트 파일 목록을로드합니다.
- 은 속성 수정없이 (간단히) 스레드를 생성합니다.
- 각 스레드는 단일 스레드가 모든 1000 개의 파일을 열어야하는 방식으로 파일 목록이 고갈 될 때까지 미리 결정된 파일 목록에서 다음 사용 가능한 파일에 대해 여러 순차 파일 열기() 호출을 수행합니다. 이론적으로 500 개의 파일 (아직 검증되지 않음) 등을 열 수 있습니다.
우리는 스레드 수, 파일 크기 및 파일이 로컬 또는 원격 서버에 있는지 여부를 매개 변수에 따라 여러 번 테스트했습니다. 몇 가지 질문이 제기되었습니다. (원격 파일 열기)
관찰 결과
- 파일 오픈 시간은 (예상 의한 캐싱을 제기)를 통해 처음으로 높다;
- 하나의 스레드로 테스트 응용 프로그램을 실행하면 모든 원격 파일을로드하는 데 X 초가 걸립니다.
- 시스템에서 사용 가능한 CPU 수와 스레드 수를 1로 계산하여 앱을 실행하면 CPU 수 (nX 초)에 비례 한 시간이 걸리는 것으로 보입니다.
- 스레드 수> #CPUs를 사용하여 응용 프로그램을 실행하면 #CPUs 스레드로 실행하는 데 걸리는 시간과 대략 동일한 값으로 수평이되는 것처럼 보이는 런타임이 발생합니다 (우연의 일치입니까, 체계적인 한도입니까? ?).
- 여러 동시 프로세스 (예 : 동일한 테스트 응용 프로그램의 동시 인스턴스 25 개)를 실행하면 선택한 스레드 수에 대한 프로세스 수와 대략 선형 인 시간이됩니다.다른 서버에 응용 프로그램을 실행
- 는 (로컬에 존재하는 파일 열기) 비슷한 결과
관찰 된 결과를 보여줍니다 크기 빠른 시간
- 주문 (예상 할 수있는대로를);
- 스레드 수를 늘리면 약 4-5 개의 활성 스레드에서 LOW 타이밍 변곡점이 발생하고 스레드 수가 CPU 수와 같아 질 때까지 다시 증가하고 다시 레벨이 해제됩니다.
- 여러 개의 동시 프로세스 (동일한 테스트)를 실행하면 일정한 스레드 수에 대한 프로세스 수와 대략 선형 인 시간이됩니다 (위의 5 번과 동일한 결과).
또한 로컬 열기는 약 .01 ms이고 순차적 네트워크 열기는 1ms에서 100 배 느리다는 것을 알았습니다. 네트워크 파일을 열면 8 개의 스레드로 최대 8 배의 선형 처리량이 증가하지만 9 개 이상의 스레드는 아무 것도 처리하지 않습니다. 8 회의 동시 요청 이후에 네트워크 공개 통화가 차단되는 것 같습니다. 우리가 예상 한 것은 네트워크 라운드 트립과 동일한 초기 지연이었고 로컬과 거의 동일한 처리량이었습니다. 아마도 100 배 이상 오래 걸리는 로컬 및 원격 시스템에서 수행되는 추가 뮤텍스 잠금이있을 수 있습니다. 초래
- 실행 여러 스레드 : 아마도에만 8
예상 결과와 질문이 이와 같은 포럼에서 테스트 또는 답변에 의해 하나 답변을 보유하고 원격 호출의 일부 내부 큐가 더 짧은 시간에 동일한 작업;
- 최적의 스레드 수가 있습니까?
- 스레드 수와 사용 가능한 CPU 수 사이에 관계가 있습니까?
- 8-10 파일 제한이 준수되는 다른 체계적인 이유가 있습니까?
- "open()"에 대한 시스템 호출이 멀티 스레딩 프로세스에서 어떻게 작동합니까?
- 각 스레드는 컨텍스트 전환 시간 슬라이스를 얻습니다.
- open() 호출이 차단되고 파일이 파일 캐시로 열리거나로드 될 때까지 대기합니까? 또는 작업이 진행되는 동안 호출이 컨텍스트 전환을 허용합니까?
- open()이 완료되면 스케줄러가 해당 스레드의 우선 순위를 다시 지정하여 스레드가 라운드 로빈 방식으로 돌아갈 때까지 대기해야합니까?
- 1000 개의 파일이있는 마운트 볼륨이 읽기 전용으로 설정되었거나 읽기/쓰기로 설정하면 차이가 있습니까?
- 전체 경로와 함께 open()이 호출되면 stat() 경로의 각 요소가? 파일 트리 목록에서 공통 디렉토리를 열고() 공용 디렉토리 아래에있는 파일을 상대 경로로 open()하는 것이 더 합리적입니까?
개발 테스트 설정 :
Red Hat Enterprise Linux Server release 5.4 (Tikanga)
8-CPUS, each with characteristics as shown below:
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Xeon(R) CPU X5460 @ 3.16GHz
stepping : 6
cpu MHz : 1992.000
cache size : 6144 KB
physical id : 0
siblings : 4
core id : 1
cpu cores : 4
apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall lm constant_tsc pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr sse4_1 lahf_lm
bogomips : 6317.47
clflush size : 64
cache_alignment : 64
address sizes : 38 bits physical, 48 bits virtual
power management:
GNU C compiler, version:
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)
Dude, 많은 질문 중 하나입니다. 가독성을 높이려면 btw 형식을 읽어보십시오. – mvds
그래서 벤치 마크 된 그래프를 삽입 할 수 있다면 정말 유용 할 것입니다. – stsquad