Я использую CentOS 5.4 x86_64 и Повышение 1.42.0 на кластере, который использует Открытые-MPI 1.3.3. Я пишу общую библиотеку, которая использует общую память для хранения больших объемов данных для нескольких процессов для использования. Существует также приложение загрузчика, которое будет читать в данных из файлов и загружать их в общую память.
Когда я запускаю приложение загрузчика, оно определяет объем памяти, что оно должно хранить данные, точно затем добавляет 25% для издержек. Для примерно каждого файла это будет более чем 2 ценности концертов данных. Когда я делаю запрос памяти, пользующийся библиотекой Interprocess Повышения, он говорит, что успешно зарезервировал требуемый объем памяти. Но когда я использую, начинают использовать его, я получаю "Ошибку шины". Из того, что я могу сказать, ошибка шины является результатом доступа к памяти вне диапазона, который доступен для сегмента памяти.
Таким образом, я начал изучать, как общая память находится на Linux и что проверить, чтобы удостовериться, что моя система правильно настроена, чтобы признать что большой объем общей памяти.
/proc/sys/kernel/shm*
: shmall
- 4294967296 (4 Гбита)shmmax
- 68719476736 (68 Гбит)shmmni
- 4096ipcs -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
#include
#include
#include
namespace bip = boost::interprocess;
typedef bip::managed_shared_memory::segment_manager segment_manager_t;
typedef bip::allocator long_allocator;
typedef bip::vector 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
), это предварительно выделяет вектор, но все еще приведет к ошибке шины в том же индексе массива.
Я проверил размер "файлов" в /dev/shm
использование ls -ash /dev/shm
команда:
total 2.0G 0 . 0 .. 2.0G ShmTest
И точно так же, как с моим исходным приложением это размер выделенной общей памяти ограничивается на 2 концертах. Учитывая, что это "успешно" выделило 2352000000 байтов памяти, в гигабайтах (использующий 1024*1024*1024) это должны быть 2,19 Гбита.
Когда я запускаю свою фактическую программу для загрузки данных с помощью MPI, я получаю этот вывод ошибок:
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). --------------------------------------------------------------------------
Я действительно не уверен, куда пойти с этим. У кого-либо есть какие-либо предложения того, что попробовать?
Отправленный на ошибку Повышения trac в: https://svn.boost.org/trac/boost/ticket/4374
Что ж, если вы продолжите искать ответ достаточно долго ...
В Linux механизмы общей памяти, которые он использует ( tmpfs
) по умолчанию, ограничивают это вдвое меньше оперативной памяти системы. Итак, в моем кластере это 2 ГБ, потому что у нас 4 ГБ оперативной памяти. Поэтому, когда он пытался выделить сегмент разделяемой памяти, он выделял до максимального размера, оставшегося на / dev / shm
.
Но проблема возникла, когда библиотека Boost не показывала ошибку или даже не сообщала правильный объем свободной памяти, когда не могла выделить запрошенный объем памяти. Он просто был счастлив, видимо, пыхтел, пока не достиг конца сегмента, а затем выдал ошибку.
Долгосрочным решением является обновление файла / etc / fstab
для внесения изменений навсегда, но можно запустить вызов командной строки для увеличения размера доступной разделяемой памяти на каждом узле до перезагрузки. .
mount -o remount, size = XXX / dev / shm
Где XXX
- это объем памяти, который нужно сделать доступным (например, size = 4G
).
Это было вычислено / взято из http: //www.cyberciti.biz / tips / what-is-devshm-and-its-Practical-usage.html