【问题标题】:Boost::Interprocess Shared Memory Bus ErrorBoost::进程间共享内存总线错误
【发布时间】:2011-03-07 09:43:28
【问题描述】:

我在使用 Open-MPI 1.3.3 的集群上使用 CentOS 5.4 x86_64 和 Boost 1.42.0。我正在编写一个共享库,它使用共享内存来存储大量数据供多个进程使用。还有一个加载器应用程序,它将从文件中读取数据并将它们加载到共享内存中。

当我运行加载器应用程序时,它会确定准确存储数据所需的内存量,然后增加 25% 的开销。对于几乎每个文件,它将超过 2 gigs 的数据。当我使用 Boost 的进程间库发出内存请求时,它说它已成功保留了请求的内存量。但是当我开始使用它时,我得到一个“总线错误”。据我所知,总线错误是访问内存段可用范围之外的内存的结果。

所以我开始研究 Linux 上的共享内存是怎样的,以及要检查什么以确保我的系统正确配置为允许大量共享内存。

  1. 我查看了/proc/sys/kernel/shm* 的“文件”:
    • shmall - 4294967296 (4 Gb)
    • shmmax - 68719476736 (68 Gb)
    • shmmni - 4096

  2. 我调用了ipcs -lm 命令:
    ----- 共享内存限制 --------
    最大段数 = 4096
    最大段大小(千字节)= 67108864
    最大总共享内存 (kbytes) = 17179869184
    最小段大小(字节)= 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

然后使用以下输出运行它(经过编辑使其更小):

长度:280000000 大小(长):8 要求:2240000000 请求:2352000000 已分配:2352000000 开销:224 免费:2351999776 0:矢量容量:0 免费:2351999776 2800000:矢量容量:3343205 免费:2325254128 5600000:矢量容量:8558607 免费:2283530912 8400000:矢量容量:8558607 免费:2283530912 11200000:矢量容量:13693771 免费:2242449600 14000000:矢量容量:21910035 免费:2176719488 ... 19600000:矢量容量:21910035 免费:2176719488 22400000:向量容量:35056057 免费:2071551312 ... 33600000:载体容量:35056057 免费:2071551312 36400000:矢量容量:56089691 免费:1903282240 ... 56000000:矢量容量:56089691 免费:1903282240 58800000:矢量容量:89743507 免费:1634051712 ... 89600000:矢量容量:89743507 免费:1634051712 92400000:矢量容量:143589611 免费:1203282880 ... 142800000:矢量容量:143589611 免费:1203282880 145600000:矢量容量:215384417 免费:628924432 ... 212800000:载体容量:215384417 免费:628924432 215600000:矢量容量:293999969 免费:16 ... 260400000:矢量容量:293999969 免费:16 总线错误

如果您使用 a 参数运行程序(任何都可以,只需要增加argc),它会预先分配向量,但仍会在相同的数组索引处导致总线错误。

我使用ls -ash /dev/shm 命令检查了/dev/shm 的“文件”的大小:

总2.0G 0 . 0 .. 2.0G ShmTest

就像我的原始应用程序一样,分配的共享内存的大小上限为 2 gig。鉴于它“成功”分配了 2352000000 字节的内存,以 GB 为单位(使用 1024*1024*1024)它应该是 2.19 Gb。

当我运行我的实际程序以使用 MPI 加载数据时,我得到以下错误输出:

要求:2808771120 收件:2808771120 [c1-master:13894] *** 处理接收到的信号 *** [c1-master:13894] 信号:总线错误 (7) [c1-master:13894] 信号代码:(2) [c1-master:13894] 地址失败: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+0x [C1-主: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-主: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-主: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-主: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-主: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-主: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] *** 错误信息结束 *** -------------------------------------------------- ---------------------- mpirun 注意到节点 c1-master 上具有 PID 13894 的进程等级 0 在信号 7 上退出(总线错误)。 -------------------------------------------------- ----------------------

我真的不知道该去哪里。有人对尝试什么有什么建议吗?


在 Boost 错误记录中发布:https://svn.boost.org/trac/boost/ticket/4374

【问题讨论】:

    标签: c++ linux boost shared-memory boost-interprocess


    【解决方案1】:

    好吧,如果你继续寻找答案的时间足够长...

    在 Linux 上,它使用的共享内存机制 (tmpfs) 默认将其限制为系统 RAM 的一半。所以在我的集群上它是 2 Gb,因为我们有 4 Gb 系统 RAM。因此,当它尝试分配共享内存段时,它会分配到/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发现/获取的

    【讨论】:

    • 有趣。您应该在提升开发列表上发布一些内容。顺便说一句,我认为您可以接受自己的答案:) 感谢您的回答。
    • 是的,也有点沮丧。 :) 我将它发布到 Boost 错误跟踪 svn.boost.org/trac/boost/ticket/4374
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 2015-11-13
    • 2014-04-19
    • 2014-05-08
    相关资源
    最近更新 更多