Concurrent increment of value keep getting unexpected results
Closed this issue · 8 comments
Hi @greg7mdp
I found out that concurrent increment of value using parallel_flat_hash_map
keep getting unexpected results, in main.cc
,
I use 10 threads to increase value of same key 1000 times, instead of getting 10 * 1000 = 10000
, the program keep getting wrong results.
compile command
g++ -o main main.cc -isystem parallel-hashmap/ -std=c++17 -lpthread
main.cc
#include <assert.h>
#include <parallel_hashmap/phmap.h>
#include <shared_mutex>
#include <stdio.h>
#include <thread>
#include <vector>
template <typename K> using HashEqual = phmap::priv::hash_default_eq<K>;
template <typename V> using Hash = phmap::priv::hash_default_hash<V>;
template <typename K> using Allocator = phmap::priv::Allocator<K>;
template <typename K, typename V, size_t N>
using parallel_flat_hash_map =
phmap::parallel_flat_hash_map<K, V, Hash<K>, HashEqual<K>,
Allocator<phmap::priv::Pair<K, V>>, N,
std::shared_mutex>;
using Table = parallel_flat_hash_map<int, int, 10>;
static constexpr int THREADS = 10;
static constexpr int EPOCH = 1000;
static constexpr int KEY = 12345;
void Incr(Table *table) {
auto exist_fn = [](typename Table::value_type &value) { value.second += 1; };
auto emplace_fn = [](const typename Table::constructor &ctor) {
ctor(KEY, 1);
};
for (int i = 0; i < EPOCH; ++i) {
(void)table->lazy_emplace_l(KEY, exist_fn, emplace_fn);
}
}
int main() {
Table table;
std::vector<std::thread> threads;
threads.reserve(THREADS);
for (int i = 0; i < THREADS; ++i) {
threads.emplace_back([&table]() { Incr(&table); });
}
for (auto &thread : threads) {
thread.join();
}
printf("table[%d]=%d\n", KEY, table[KEY]);
assert(table[KEY] == 10000);
return 0;
}
Hi @dakabang , you are right, there is an issue with std::shared_mutex
.
If you replace it with std::mutex
you do get the expected result.
Thanks for reporting the issue. I'll have a look at it.
Thanks for your reply, I'm concerned that the implementation of std::mutex
may have performance degradation compared to std::shared_mutex
, I'm looking forward for this issue to be fixed.
Excellent! Thanks for your help.
Sure, @dakabang , I will, but I may not be able to do it before next weekend though. Thanks for the bug report (and using phmap :-)
Actually, I can tag a new release now, but will update vcpkg and conan later.
New release 1.4.1 tagged.