2013-09-16 4 views
17

У меня есть приложение, которое использует boost::interprocess::map в общей памяти. Карта содержит большое количество элементов (от 100 к до 10 М), и все работает очень хорошо, за одним исключением: необходимо периодически очищать карту, и это, по-видимому, занимает около 4 мкс на элемент (что в худшем случае 40 секунд), что неприемлемо для приложения. Похоже, что clear() фактически удаляет каждый элемент карты отдельно и ребалансирует дерево после каждого удаления, поэтому он ужасно неэффективен, когда у вас есть большое количество элементов. В идеале clear() просто удалил бы все элементы без каких-либо перебалансировок - можно ли каким-либо образом реализовать такой оптимизированный метод clear()?Более быстрый способ очистки boost :: interprocess :: map?

(Кстати, я также пытался boost:interprocess:flat_map - это имеет гораздо быстрее, очевидно, время, как можно было бы ожидать (в 10 раз быстрее), но это слишком медленно для вставки/удаления.)

Примечание: earlier question on StackOverflow прикоснулся по аналогичной проблеме с меньшими STL-картами в нормальной (то есть не разделенной) памяти, но на самом деле не решила проблему.

+5

Можете ли вы просто создать новую пустую карту, а затем удалить старый в нисходящем потоке с низким приоритетом или что-то еще? Или это слишком большая боль при координации общей памяти? – ipmcc

+0

@ipmcc: спасибо, да, я планирую экспериментировать с этим, но, как вы заметили, это испортит мою архитектуру общей памяти, если адрес карты может периодически меняться. Кроме того, у меня есть ужасное подозрение, что удаление будет столь же неэффективным, что все элементы карты будут удаляться отдельно, но мне нужно это проверить. –

+0

@PaulR Адрес карты не нужно менять: просто «свопите» свои карты.Затем вы можете переместить полную карту в поток с низким приоритетом, как предположил ipmcc. – syam

ответ

2

Глядя на код Boost, я предполагаю, что вы либо:

  • Нашли ошибку в реализации rbtree

или

  • закодированных с помощью безопасной-режим или автоматической разблокировки

От \ boost_ 1_54_0 \ импульс \ навязчивым \ rbtree.hpp

//! <b>Effects</b>: Erases all of the elements. 
    //! 
    //! <b>Complexity</b>: Linear to the number of elements on the container. 
    //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. 
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references) 
    //! to the erased elements. No destructors are called. 
    void clear() 
    { 
     if(safemode_or_autounlink){ 
     this->clear_and_dispose(detail::null_disposer()); 
     } 
     else{ 
     node_algorithms::init_header(this->priv_header_ptr()); 
     this->priv_size_traits().set_size(0); 
     } 
    } 

Комментарий здесь ясно сказано, что вы можете получить постоянное время из внедренных ясно. Пейджинг через код повышения, мое чтение заключается в том, что interprocess :: map в конечном итоге использует этот rbtree в качестве базовой структуры данных. Я не заметил, что были установлены безопасные или автоматические развязки, но я мог пропустить это. Если вы установили один из них, я бы сначала посмотрел, смогу ли я жить без него, и если да, то проблемы с производительностью, надеюсь, уйдут.

Если это ошибка в boost, вам придется обойти ее. Я бы немедленно сообщить об этом, используя контактную информацию в заголовке:

///////////////////////////////////////////////////////////////////////////// 
// 
// (C) Copyright Ion Gaztanaga 2006-2012 
// 
// Distributed under the Boost Software License, Version 1.0. 
// (See accompanying file LICENSE_1_0.txt or copy at 
//   http://www.boost.org/LICENSE_1_0.txt) 
// 
// See http://www.boost.org/libs/intrusive for documentation. 
// 
///////////////////////////////////////////////////////////////////////////// 

появляется быстрый поиск Google, чтобы иметь контактную информацию для Ion в:

http://boost.2283326.n4.nabble.com/template/NamlServlet.jtp?macro=user_nodes&user=161440

Или собирается http://www.boost.org/development/bugs.html

И затем реализуйте решение Paul R или rileyberton в зависимости от вашего уровня производительности.

Смежные вопросы