2010-07-14 2 views
12

Linux에서 C/C++의 경우 이더넷 포트에 연결된 센서의 실시간 데이터를 저장하고 데이터를 스트리밍하기 위해 큰 (수 기가 바이트) 블록을 할당해야합니다. 약 110MB/s. 저장할 수있는 데이터 시퀀스의 길이를 최대화하기 위해 최대한 많은 양의 메모리를 할당하고 싶습니다. 그러나 결과적으로 디스크 액세스의 지연과 제한된 대역폭으로 인해 센서의 (매우 제한적인) 버퍼 오버플로가 발생하기 때문에 디스크 스와핑이 발생하지 않도록해야합니다.스왑을 사용하지 않고 최대 버퍼 할당

할당 할 메모리 양을 결정하는 가장 좋은 방법은 무엇입니까? 보고 된 사용 가능한 메모리보다 약간 작은 블록을 할당하는 것으로 제한 되었습니까? 아니면 Linux 가상 메모리 관리자와 직접 더 직접 인터페이스 할 수 있습니까?

+0

정말 관심이 없으므로 사용중인 센서는 무엇입니까? – Konrad

+0

중복 된 http://stackoverflow.com/questions/2513505/ –

+0

@ Space_C0wb0y : 실제로는 아닙니다. – Hasturkun

답변

9

음, 리눅스에서 사용할 수있는 MLOCK()/mlockall() 물리 메모리에 ADRESS 범위를 유지하고 스왑 아웃되는 것을 방지하기 위해. mlock을 사용하는 프로세스에는 이렇게하는 데 필요한 몇 가지 권한이 필요합니다. "man mlock"에는 자세한 내용이 있습니다. 내가 최대 mlock'able 블록 (그것은 "무료"것 같다 다를 수 있습니다), 그래서 아마도 이진 검색 (잠금 영역, 등등 영역의 크기를 줄이면 실패합니다.)에 대해 확실하지 않다.

반면에 110MB/s는 솔리드 스테이트 드라이브에 실제로 문제가되지 않습니다. 280MB/s의 쓰기 속도를 가진 60GB SSD는 구석에 약 200 달러가 든다. 센서 데이터를 작은 쓰기 버퍼에 복사하고 SSD로 스트리밍하면됩니다.

0

필요한 양의 메모리와 해당 속도로 쓰기 작업을 수행하는 경우 모든 페이지 오류 (예 : 가상 메모리의 각 페이지에 실제 메모리에 매핑하는 성능 저하가 발생합니다. 다른 프로세스의 메모리를 스왑 아웃).

센서에서 읽기를 시작하기 전에 memset 전체 할당 된 버퍼를 0으로 설정하여 필요한 모든 가상 메모리가 실제 메모리에 매핑되도록 할 수 있습니다.

사용 가능한 물리적 메모리가 인 경우에만 스와핑이 발생하지 않아야합니다. more를 사용하면 다른 프로세스의 메모리가 디스크로 스왑됩니다. 이러한 프로세스가 유휴 상태이면 문제가 발생하지 않습니다. 사용 중이면 (즉, 한동안 메모리를 사용하는 경우) 하드 드라이브 대역폭보다 훨씬 낮은 속도로 스와핑이 발생합니다. 사용하는 메모리가 많을수록 더 많은 활성 프로세스의 메모리가 스왑 아웃되고 더 많은 HD 활동이 발생합니다.이 시점에서 적절한 성능으로 사용할 수있는 최대 메모리 양은 시행 착오의 결과입니다.

사용 가능한 실제 메모리 이상을 사용하면 확실히 메모리 쓰기 속도로 스와핑이 발생하므로이를 피할 방법이 없습니다.

+2

물리적 메모리를 할당하기 위해 시스템을 속이기 위해'memset()'을 사용할 필요가 없습니다. 명시 적으로하려면'mlock()'을 사용하고 절대 스왑 아웃하지 않도록하십시오. –

+0

감사합니다. –

0

할당 할 메모리 양을 결정하는 가장 좋은 방법은 무엇입니까?

가상 메모리가 사용되는 방식 (스왑 불가능한 커널 메모리)으로 인해 응용 프로그램이 설치된 메모리의 양을 식별하는 것은 거의 불가능합니다.

최선의 방법은 사용자가 버퍼링에 사용할 메모리 양을 구성 할 수 있도록하는 것입니다.

보고 사용 가능한 메모리는 정말 아니다, 난 그냥보고 사용 가능한 메모리보다 약간 작은 블록을 할당에 제한이 있습니까 "사용 가능한 실제 메모리." 운수 나쁘게.

또는 Linux 가상 메모리 관리자와 직접 더 인터페이스 할 수 있습니까?

사용자 정의 장치 드라이버를 사용하여 커널 공간에 직접 메모리를 할당하고 mmap()을 통해 액세스를 제공함으로써이를 수행 할 수 있습니다. 일반적으로 권장하지는 않지만 귀하와 같은 특수한 경우에는 작동합니다.거기에는 디스크 스와핑 리눅스 커널 개발의 속도로

, 지식은 매우 빠른 더 이상 사용되지 수 없기 때문에, 소금의 곡식 걸릴 것으로

그러나 나는 또한 확인해야 내가 내가 여기서 말하는거야. 다음과 같이 게임을 시도해보십시오.

  1. SysV 공유 메모리. 그것은 일반적으로 교환되지 않습니다. man shmget을 참조하십시오.

  2. tmpfs - 메모리 파일 시스템. 메모리는 적어도 2.6 커널 초기에 RAM에 고정되었으므로 교체 할 수 없었습니다. 그것을 메모리로 사용하려면 파일에 tmpfs에 write() 무언가를 만들어 (메모리가 실제로 할당되도록) 강제로 파일을 mmap()하십시오.

+0

레코드 만 있으면 실제로 * tmpfs *가 스왑 가능합니다. 스왑되지 않는 또 다른 변형 * rootfs *가 있습니다. 그러나 이것 때문에 당신은 그것으로 정말로 조심해야만하고 그것을 과도하게해서는 안됩니다. –

0

당신이 당신의 메모리를 할당 한 후에는

echo 0 > /proc/sys/vm/swappiness 

캐시에서 메모리를 회수하는 대신 교환 선호하는 커널을 요청하려면 수 있습니다.

그냥 내 $ 0.2

+1

질문은 스와핑을 방지하는 방법을 묻는 것이 아니라 스왑없이 메모리를 할당 할 수있는 방법을 결정하는 방법을 묻습니다. 그리고 메모리 관리자에 대한 시스템 차원의 해킹이 아니라'mlock()'을 사용하여 특정 버퍼에 대한 스와핑을 방지 할 수 있습니다. –

+0

고마워, 잘 알고있다. :) – miedwar

3

컴퓨터 시스템이 센서의 데이터 수신 전용 인 경우 단순히 스왑을 비활성화 할 수 있습니다. 가능한 한 큰 버퍼로 할당하여 필수 도구에 대해서만 시스템에 충분한 메모리를 남겨 둡니다.

+0

슬프게도 그것은 헌신적 인 시스템이 아닙니다. 그러나 다른 용도로 사용하기에는 많은 양의 RAM이 있으므로 스왑을 사용하지 않도록 설정하는 것이 좋습니다. –

+0

얼마 동안 메모리 사용량을 확인하십시오. 일부 응용 프로그램이 메모리를 새기 시작하지 않으면 스왑이 거의 사용되지 않습니다. 저는 스왑이없는 데스크탑 시스템을 아무런 문제없이 실행했습니다. 그러나 더 일반적인 해결책을 위해 루터 (Luther)가 권고 한 바와 같이 mlock (2)을 사용하십시오. 모든 것을 하나의 연속 버퍼로 할당하지 마십시오. 메모리 관리자가 문제를 할당 (또는 재 할당)했을 수 있습니다. 인터페이스에 의해 하나에 연결된 더 작은 많은 버퍼를 사용하십시오. 예를 들면 다음과 같이 할 수 있습니다. 런타임에 버퍼 크기를 조정하십시오. –

+0

"buffor"맞춤법에 대한 엄지 손가락 업 : P! – Cray

관련 문제