2010-06-23 10 views
9

Open-MPI 1.3.3을 사용하는 클러스터에서 CentOS 5.4 x86_64 및 Boost 1.42.0을 사용하고 있습니다. 공유 메모리를 사용하여 여러 프로세스에서 사용할 많은 양의 데이터를 저장하는 공유 라이브러리를 작성 중입니다. 또한 파일에서 데이터를 읽어 들여 공유 메모리에로드하는 로더 응용 프로그램이 있습니다.Boost :: 프로세스 간 공유 메모리 버스 오류

로더 응용 프로그램을 실행할 때 데이터를 정확하게 저장해야하는 메모리 양이 결정되어 오버 헤드에 25 %가 추가됩니다. 거의 모든 파일에 대해 2 기가 이상의 가치가있는 데이터입니다. Boost의 Interprocess 라이브러리를 사용하여 메모리 요청을하면, 요청 된 메모리 양을 성공적으로 예약했다고합니다. 그러나 시작을 사용하여 시작할 때 "버스 오류"가 발생합니다. 내가 알 수 있듯이 버스 오류는 메모리 세그먼트에 사용할 수있는 범위 밖의 메모리에 액세스 한 결과입니다.

그래서 공유 메모리가 리눅스에 어떻게 설치되어 있는지, 내 시스템이 대량의 공유 메모리를 허용하도록 올바르게 구성되었는지 확인하기 시작했습니다. 4294967296 (4 GB)

  • shmmax - - 68,719,476,736 (68 GB)
  • shmmni-4096

    • shmall :

      1. 나는 /proc/sys/kernel/shm*에서 "파일"바라 보았다
      2. 나는 ipcs -lm 명령을 호출했다.
        ------ Shared Memory Limits -------- 
        max number of segments = 4096 
        max seg size (kbytes) = 67108864 
        max total shared memory (kbytes) = 17179869184 
        min seg size (bytes) = 1

      내가 알 수있는 바로는, 이러한 설정은 내 용도로 충분한 공유 메모리를 할당 할 수 있어야한다는 것을 나타냅니다. 라인으로 컴파일 된

      
      #include <iostream> 
      
      #include <boost/interprocess/managed_shared_memory.hpp> 
      #include <boost/interprocess/allocators/allocator.hpp> 
      #include <boost/interprocess/containers/vector.hpp> 
      
      namespace bip = boost::interprocess; 
      
      typedef bip::managed_shared_memory::segment_manager segment_manager_t; 
      typedef bip::allocator<long, segment_manager_t> long_allocator; 
      typedef bip::vector<long, long_allocator> long_vector; 
      
      int main(int argc, char ** argv) { 
          struct shm_remove { 
           shm_remove() { bip::shared_memory_object::remove("ShmTest"); } 
           ~shm_remove() { bip::shared_memory_object::remove("ShmTest"); } 
          } remover; 
      
          size_t szLength = 280000000; 
          size_t szRequired = szLength * sizeof(long); 
          size_t szRequested = (size_t) (szRequired * 1.05); 
          bip::managed_shared_memory segment(bip::create_only, "ShmTest", szRequested); 
      
          std::cout << 
           "Length:  " << szLength << "\n" << 
           "sizeof(long): " << sizeof(long) << "\n" << 
           "Required:  " << szRequired << "\n" << 
           "Requested: " << szRequested << "\n" << 
           "Allocated: " << segment.get_size() << "\n" << 
           "Overhead:  " << segment.get_size() - segment.get_free_memory() << "\n" << 
           "Free:   " << segment.get_free_memory() << "\n\n"; 
      
          long_allocator alloc(segment.get_segment_manager()); 
          long_vector vector(alloc); 
      
          if (argc > 1) { 
           std::cout << "Reserving Length of " << szLength << "\n"; 
           vector.reserve(szLength); 
           std::cout << "Vector Capacity: " << vector.capacity() << "\tFree: " << segment.get_free_memory() << "\n\n"; 
          } 
      
          for (size_t i = 0; i < szLength; i++) { 
           if ((i % (szLength/100)) == 0) { 
            std::cout << i << ": " << "\tVector Capacity: " << vector.capacity() << "\tFree: " << segment.get_free_memory() << "\n"; 
           } 
           vector.push_back(i);  
          } 
          std::cout << "end: " << "\tVector Capacity: " << vector.capacity() << "\tFree: " << segment.get_free_memory() << "\n"; 
      
          return 0; 
      } 
      

      : 그래서 공유 메모리에 많은 양의 데이터를 만든 옷을 벗었 프로그램 생성

      g++ ShmTest.cpp -lboost_system -lrt

      그런 다음 다음과 같은 출력을 실행을 (더 작게 만들기 위해 편집) :

       
      Length:  280000000 
      sizeof(long): 8 
      Required:  2240000000 
      Requested: 2352000000 
      Allocated: 2352000000 
      Overhead:  224 
      Free:   2351999776 
      
      0:  Vector Capacity: 0  Free: 2351999776 
      2800000:  Vector Capacity: 3343205  Free: 2325254128 
      5600000:  Vector Capacity: 8558607  Free: 2283530912 
      8400000:  Vector Capacity: 8558607  Free: 2283530912 
      11200000:  Vector Capacity: 13693771  Free: 2242449600 
      14000000:  Vector Capacity: 21910035  Free: 2176719488 
      ... 
      19600000:  Vector Capacity: 21910035  Free: 2176719488 
      22400000:  Vector Capacity: 35056057  Free: 2071551312 
      ... 
      33600000:  Vector Capacity: 35056057  Free: 2071551312 
      36400000:  Vector Capacity: 56089691  Free: 1903282240 
      ... 
      56000000:  Vector Capacity: 56089691  Free: 1903282240 
      58800000:  Vector Capacity: 89743507  Free: 1634051712 
      ... 
      89600000:  Vector Capacity: 89743507  Free: 1634051712 
      92400000:  Vector Capacity: 143589611  Free: 1203282880 
      ... 
      142800000:  Vector Capacity: 143589611  Free: 1203282880 
      145600000:  Vector Capacity: 215384417  Free: 628924432 
      ... 
      212800000:  Vector Capacity: 215384417  Free: 628924432 
      215600000:  Vector Capacity: 293999969  Free: 16 
      ... 
      260400000:  Vector Capacity: 293999969  Free: 16 
      Bus error 
      

      당신이 매개 변수 (모든 단지 argc을 증가시킬 필요가 작동합니다)와 함께 프로그램을 실행하면,이 벡터를 미리 할당하지만 여전히 BU가 발생합니다 동일한 배열 인덱스에서 오류가 발생했습니다.

       
      total 2.0G 
          0 .  0 .. 2.0G ShmTest 
      

      그리고 내 원래 응용 프로그램과 마찬가지로이 할당 된 공유 메모리의 크기가 2 기가에 덮인된다

      은 내가 ls -ash /dev/shm 명령을 사용하여 /dev/shm에서 "파일"의 크기를 확인. "성공적으로"2352000000 바이트의 메모리를 할당하면 기가 바이트 (1024 * 1024 * 1024 사용)로 2.19GB가되어야합니다.

       
      Requested: 2808771120 
      Recieved: 2808771120 
      
      [c1-master:13894] *** Process received signal *** 
      [c1-master:13894] Signal: Bus error (7) 
      [c1-master:13894] Signal code: (2) 
      [c1-master:13894] Failing at address: 0x2b3190157000 
      [c1-master:13894] [ 0] /lib64/libpthread.so.0 [0x3a64e0e7c0] 
      [c1-master:13894] [ 1] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN5boost12interprocess26uninitialized_copy_or_moveINS0_10offset_ptrIlEEPlEET0_T_S6_S5_PNS_10disable_ifINS0_11move_detail16is_move_iteratorIS6_EEvE4typeE+0x218) [0x2b310dcf3fb8] 
      [c1-master:13894] [ 2] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN5boost9container6vectorIlNS_12interprocess9allocatorIlNS2_15segment_managerIcNS2_15rbtree_best_fitINS2_12mutex_familyENS2_10offset_ptrIvEELm0EEENS2_10iset_indexEEEEEE15priv_assign_auxINS7_IlEEEEvT_SG_St20forward_iterator_tag+0xa75) [0x2b310dd0a335] 
      [c1-master:13894] [ 3] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN5boost9container17containers_detail25advanced_insert_aux_proxyINS0_6vectorIlNS_12interprocess9allocatorIlNS4_15segment_managerIcNS4_15rbtree_best_fitINS4_12mutex_familyENS4_10offset_ptrIvEELm0EEENS4_10iset_indexEEEEEEENS0_17constant_iteratorISF_lEEPSF_E25uninitialized_copy_all_toESI_+0x1d7) [0x2b310dd0b817] 
      [c1-master:13894] [ 4] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN5boost9container6vectorINS1_IlNS_12interprocess9allocatorIlNS2_15segment_managerIcNS2_15rbtree_best_fitINS2_12mutex_familyENS2_10offset_ptrIvEELm0EEENS2_10iset_indexEEEEEEENS3_ISD_SB_EEE17priv_range_insertENS7_ISD_EEmRNS0_17containers_detail23advanced_insert_aux_intISD_PSD_EE+0x771) [0x2b310dd0d521] 
      [c1-master:13894] [ 5] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN5boost12interprocess6detail8Ctor3ArgINS_9container6vectorINS4_IlNS0_9allocatorIlNS0_15segment_managerIcNS0_15rbtree_best_fitINS0_12mutex_familyENS0_10offset_ptrIvEELm0EEENS0_10iset_indexEEEEEEENS5_ISF_SD_EEEELb0EiSF_NS5_IvSD_EEE11construct_nEPvmRm+0x157) [0x2b310dd0d9a7] 
      [c1-master:13894] [ 6] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN5boost12interprocess15segment_managerIcNS0_15rbtree_best_fitINS0_12mutex_familyENS0_10offset_ptrIvEELm0EEENS0_10iset_indexEE28priv_generic_named_constructIcEEPvmPKT_mbbRNS0_6detail18in_place_interfaceERNS7_INSE_12index_configISB_S6_EEEENSE_5bool_ILb1EEE+0x6fd) [0x2b310dd0c85d] 
      [c1-master:13894] [ 7] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN5boost12interprocess15segment_managerIcNS0_15rbtree_best_fitINS0_12mutex_familyENS0_10offset_ptrIvEELm0EEENS0_10iset_indexEE22priv_generic_constructEPKcmbbRNS0_6detail18in_place_interfaceE+0xf8) [0x2b310dd0dd58] 
      [c1-master:13894] [ 8] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN7POP_LTL16ExportPopulation22InitializeSharedMemoryEPKc+0x1609) [0x2b310dceea99] 
      [c1-master:13894] [ 9] ../LookupPopulationLib/Release/libLookupPopulation.so(_ZN7POP_LTL10InitializeEPKc+0x349) [0x2b310dd0ebb9] 
      [c1-master:13894] [10] MPI_Release/LookupPopulation.MpiLoader(main+0x372) [0x4205d2] 
      [c1-master:13894] [11] /lib64/libc.so.6(__libc_start_main+0xf4) [0x3a6461d994] 
      [c1-master:13894] [12] MPI_Release/LookupPopulation.MpiLoader(__gxx_personality_v0+0x239) [0x420009] 
      [c1-master:13894] *** End of error message *** 
      -------------------------------------------------------------------------- 
      mpirun noticed that process rank 0 with PID 13894 on node c1-master exited on signal 7 (Bus error). 
      -------------------------------------------------------------------------- 
      

      난 정말이 함께 갈 곳 확실하지 않다 :

      내가 MPI를 사용하여 데이터를로드하는 내 실제 프로그램을 실행

      , 나는이 오류 출력을 얻을. 누구든지 시도해 볼만한 제안이 있습니까?당신은 충분히 답을 찾고 유지하는 경우 리눅스에 ..., https://svn.boost.org/trac/boost/ticket/4374

    답변

    8

    음이 사용하는 공유 메모리 메커니즘 (tmpfs)에 의해을

    을 :

    은 부스트 ​​버그 TRAC에 게시 기본값은 시스템 RAM의 절반으로 제한합니다. 따라서 우리 클러스터에는 4GB 시스템 RAM이 있기 때문에 2GB입니다. 따라서 공유 메모리 세그먼트를 할당하려고 시도했을 때 /dev/shm에 남아있는 최대 크기까지 할당했습니다.

    그러나 Boost 라이브러리가 요청 된 메모리 양을 할당 할 수 없을 때 오류 또는 심지어 올바른 사용 가능한 메모리 양을 나타내지 않은 경우 문제가 발생했습니다. 세그먼트의 끝 부분에 도달하여 오류가 날 때까지 계속 삐걱 거리는 것만으로도 행복했습니다.

    장기적인 해결책은 변경을 영구적으로 수행하기 위해 /etc/fstab 파일을 업데이트하는 것이지만 재부팅 할 때까지 각 노드에서 사용 가능한 공유 메모리의 크기를 늘리려면 명령 줄 호출을 실행할 수 있습니다. XXX 메모리의 양 (예 size=4G위한)을 사용할 수 있도록하는 것이다

    mount -o remount,size=XXX /dev/shm

    .

    이 내용은 다음에서 계산되었습니다. http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html

    +1

    흥미 롭습니다. 당신은 부스트 ​​개발 목록에 뭔가를 게시해야합니다. 그건 그렇고, 난 당신이 대답을 수락 할 수 있다고 생각 :) 답변 주셔서 감사합니다. – neuro

    +0

    네, 약간 실망 스럽군요. :) 나는 https://svn.boost.org/trac/boost/ticket/4374에서 Boost bug tracking에 그것을 게시했다. – CuppM