2013-10-15 5 views
0

많은 메모리가 필요한 C++에서 컴퓨터 시뮬레이션을 작성했습니다. 반복에서 실행되고 각 반복에서 반복의 끝에서 해제되어야하는 많은 양의 메모리가 할당됩니다. 또한 C++ 11의 구현 인 <thread>을 사용하여 항목을 병렬로 실행합니다.C++ 프로그램이 다른 컴퓨터에서 매우 다른 메모리 동작을 보여줍니다.

데스크톱 컴퓨터에서 프로그램을 테스트 할 때 정상적으로 작동합니다. 허용하는 메모리를 초과하지 않으며 시간과 반복 동안 아무 것도 쌓지 않습니다. 그러나 계산 클러스터에 프로그램을 제출하면 사용 된 메모리 (대기열에있는 소프트웨어를 통해서만 액세스 할 수 있음)가 시간이 지남에 따라 커지고 내 컴퓨터에서 사용되는 메모리를 훨씬 초과합니다.

것은 내가 먼저 아주 거칠게 소프트웨어가 어떻게 구성되어 있는지를 보여 드리죠 :

for thread in n_threads: 
    vector<Object> container; 
    for iteration in simulation: 
     container.clear() 
     container.resize(a_large_number) 
     ... do stuff ... 

컨테이너의 메모리 2GB을 먹고 내 컴퓨터에의가 있다고 가정 해 봅시다. htopvalgrind --tool=massif에서이 두 가지를 모두 볼 수 있습니다.이 2GB은 절대로 초과하지 않았습니다. 아무것도 쌓이지 않습니다. 그러나 클러스터에서는 2GB 이상이 될 때까지 메모리가 증가하고 커질 수 있습니다 (작업이 종료되거나 계산 노드가 정지 함). 두 컴퓨터의 스레드 수를 제한하고 이들이 동일하다는 것을 확인할 수 있습니다.

내가 아는 바로는 클러스터의 libc이 매우 오래된 것입니다. 프로그램을 컴파일하려면 g++의 새 버전을 컴파일하고 클러스터의 프론트 노드에서 libc을 업데이트해야했습니다. 소프트웨어는 계산 노드에서 잘 실행되지만 (이 메모리 문제는 제외), libc는 훨씬 오래되었습니다. 이것이 메모리 할당을위한 특히 스레딩과 관련된 문제 일 수 있습니까? 어떻게 그걸 조사 할 수 있니?

답변

1

예, GNU libc의 나이에 따라 몇 가지 중요한 메모리 할당 최적화가 누락되었을 수 있습니다. 여기에 시도 할 몇 가지 (위험, 말할 필요도없이 성능 저하)은 다음과 같습니다

  1. 당신은 mallopt() 통해의 malloc/무료 동작을 조정 시도 할 수

    는; M_MMAP_MAXM_MMAP_THRESHOLD 옵션을 사용하여 할당량이 mmap()이되도록 권장하십시오. 이렇게하면 free() 이후에 메모리가 시스템에 반환됩니다.

  2. 컨테이너의 할당자가 __gnu_cxx::malloc_allocator이되도록하여 mallopt() 개조가 컨테이너에 영향을 미치는지 확인하십시오.

  3. 크기 변경 후 container.shrink_to_fit()을 호출하여 벡터가 엄격하게 필요한 것보다 많은 메모리를 보류하고 있지 않은지 확인하십시오.

+0

안녕하세요. 의견을 보내 주셔서 감사합니다. 세 번째 옵션을 시도했지만 도움이되지 않았습니다. 내 코드와 클러스터의 libpthread (또는 일반적으로 libc) 사이의 상호 작용에있어 근본적인 문제가있는 것처럼 보입니다. 모든 것을 단일 스레드, 즉 주 스레드로 제한하면 모든 시스템에서 정상적으로 작동합니다. 클러스터 OS가 너무 오래되어 새로운 libc를 쉽게 컴파일 할 수 있기 때문에 지금은 포기했습니다. 그것은 단일 스레드입니다. – janoliver