From 08bf909e2b23f6bb092a1098e951a36945f0a659 Mon Sep 17 00:00:00 2001 From: Justin Viiret Date: Tue, 6 Jun 2017 14:37:18 +1000 Subject: [PATCH] ng_violet: make calcSplitRatio operation faster Implements count_reachable in a less malloc-happy way, improving compile performance. Adds a count() function to small_color_map. --- src/nfagraph/ng_violet.cpp | 28 ++++++++++++++++++++-------- src/util/graph_small_color_map.h | 17 ++++++++++++++++- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/nfagraph/ng_violet.cpp b/src/nfagraph/ng_violet.cpp index 9ce732c2..78d73082 100644 --- a/src/nfagraph/ng_violet.cpp +++ b/src/nfagraph/ng_violet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Intel Corporation + * Copyright (c) 2016-2018, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -60,6 +60,7 @@ #include "util/flat_containers.h" #include "util/graph.h" #include "util/graph_range.h" +#include "util/graph_small_color_map.h" #include "util/insertion_ordered.h" #include "util/make_unique.h" #include "util/order_check.h" @@ -133,14 +134,21 @@ bool createsTransientLHS(const NGHolder &g, const vector &vv, return true; } +/** + * Counts the number of vertices that are reachable from the set of sources + * given. + */ static -double calcSplitRatio(const NGHolder &g, const vector &vv) { - flat_set not_reachable; - find_unreachable(g, vv, ¬_reachable); - double rv = (double)not_reachable.size() / num_vertices(g); - rv = rv > 0.5 ? 1 - rv : rv; +size_t count_reachable(const NGHolder &g, const vector &sources, + small_color_map &color_map) { + auto null_visitor = boost::make_dfs_visitor(boost::null_visitor()); + color_map.fill(small_color::white); - return rv; + for (auto v : sources) { + boost::depth_first_visit(g, v, null_visitor, color_map); + } + + return color_map.count(small_color::black); } static @@ -687,8 +695,12 @@ unique_ptr findBestSplit(const NGHolder &g, } if (last_chance) { + const size_t num_verts = num_vertices(g); + auto color_map = make_small_color_map(g); for (auto &a : lits) { - a->split_ratio = calcSplitRatio(g, a->vv); + size_t num_reachable = count_reachable(g, a->vv, color_map); + double ratio = (double)num_reachable / (double)num_verts; + a->split_ratio = ratio > 0.5 ? 1 - ratio : ratio; } } diff --git a/src/util/graph_small_color_map.h b/src/util/graph_small_color_map.h index 03e61cf4..249b7153 100644 --- a/src/util/graph_small_color_map.h +++ b/src/util/graph_small_color_map.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (c) 2017-2018, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -114,6 +114,21 @@ public: std::memset(data->data(), val, data->size()); } + size_t count(small_color color) const { + assert(static_cast(color) < sizeof(fill_lut)); + size_t num = 0; + for (size_t i = 0; i < n; i++) { + size_t byte = i / entries_per_byte; + assert(byte < data->size()); + size_t bit = (i % entries_per_byte) * bit_size; + u8 val = ((*data)[byte] >> bit) & bit_mask; + if (static_cast(val) == color) { + num++; + } + } + return num; + } + small_color get_impl(key_type key) const { auto i = get(index_map, key); assert(i < n);