Как распараллелить разбор области либосмия?

Я ищу способы сделать libosmium основанный проект для анализа областей PBF OpenStreetMap с использованием нескольких потоков. Синтаксический анализ узлов, путей или отношений является многопоточным, а синтаксический анализ — нет.

Например, при выполнении следующего кода, который считает отношения, Топ показывает загрузку процессора более 400%:

#include <osmium/handler.hpp>
#include <osmium/io/pbf_input.hpp>
#include <osmium/visitor.hpp>

using namespace osmium;

struct MyHandler : public handler::Handler {
int counter = 0;
void relation(const Relation &relation) {
counter++;
}
};

int main(int argc, char *argv[]) {
io::File infile(argv[1]);
MyHandler handler;
io::Reader reader(infile);
apply(reader, handler);
reader.close();
std::cout << handler.counter << "\n";
}

Когда я изменяю его для подсчета площадей, процессор остается на уровне 100%:

#include <osmium/area/assembler.hpp>
#include <osmium/area/multipolygon_collector.hpp>
#include <osmium/handler/node_locations_for_ways.hpp>
#include <osmium/index/map/sparse_mem_array.hpp>
#include <osmium/io/pbf_input.hpp>

using namespace osmium;

using index_type = index::map::SparseMemArray<unsigned_object_id_type, Location>;
using cache_type = handler::NodeLocationsForWays<index_type>;

struct MyHandler : public handler::Handler {
int counter = 0;
void area(const Area &area) {
counter++;
}
};

int main(int argc, char *argv[]) {
// pass 1
io::File infile(argv[1]);
area::Assembler::config_type assembler_config;
area::MultipolygonCollector<area::Assembler>  collector(assembler_config);
io::Reader reader1(infile, osm_entity_bits::relation);
collector.read_relations(reader1);
reader1.close();
// pass 2
index_type index;
cache_type cache{index};
cache.ignore_errors();
MyHandler handler;
io::Reader reader2(infile);
apply(reader2, cache, collector.handler([&handler](
const memory::Buffer &&buffer) { apply(buffer, handler); }));
reader2.close();
std::cout << handler.counter << "\n";
}

Разница здесь в том, что код выполняется за 2 прохода. Первый проход собирает ссылки на области из отношений, а второй проход затем строит области, используя кэш узла и собранные данные отношений. Однако такая структура не выглядит многопоточной.

Как я могу сделать это, чтобы использовать несколько потоков? Существует ли уже существующий подход, встроенный в libosmium, или я должен начать реализовывать свои собственные пулы потоков и очереди?

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]