mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
upd: improving the broadcasting ut.
This commit is contained in:
parent
32585a39f3
commit
5578f48595
@ -122,12 +122,12 @@ void test_unicast(std::size_t np, std::size_t nc, std::size_t k) {
|
||||
typename concur::traits<PC>::context ctx {};
|
||||
for (;;) {
|
||||
std::this_thread::yield();
|
||||
std::uint64_t i;
|
||||
while (!pc.dequeue(imp::make_span(circ), hdr, ctx, i)) {
|
||||
std::uint64_t v;
|
||||
while (!pc.dequeue(imp::make_span(circ), hdr, ctx, v)) {
|
||||
if (running == 0) return;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
sum += i;
|
||||
sum += v;
|
||||
}
|
||||
};
|
||||
|
||||
@ -170,7 +170,7 @@ namespace {
|
||||
template <typename PC>
|
||||
void test_broadcast(std::size_t np, std::size_t nc, std::size_t k) {
|
||||
LIBIMP_LOG_();
|
||||
|
||||
{
|
||||
concur::element<std::uint64_t> circ[32] {};
|
||||
PC pc;
|
||||
typename concur::traits<PC>::header hdr {imp::make_span(circ)};
|
||||
@ -221,6 +221,71 @@ void test_broadcast(std::size_t np, std::size_t nc, std::size_t k) {
|
||||
ASSERT_EQ(pop_one(), (std::uint64_t)-1);
|
||||
}
|
||||
|
||||
log.info("\n\tStart with: ", imp::nameof<PC>(), ", ", np, " producers, ", nc, " consumers...");
|
||||
{
|
||||
struct Data {
|
||||
std::uint64_t n;
|
||||
std::uint64_t i;
|
||||
};
|
||||
concur::element<Data> circ[32] {};
|
||||
PC pc;
|
||||
typename concur::traits<PC>::header hdr {imp::make_span(circ)};
|
||||
ASSERT_TRUE(hdr.valid());
|
||||
|
||||
constexpr static std::uint32_t loop_size = 100'0000;
|
||||
|
||||
std::atomic<std::uint64_t> sum {0};
|
||||
std::atomic<std::size_t> running {np};
|
||||
std::array<std::atomic<std::size_t>, 64> counters {};
|
||||
|
||||
auto prod_call = [&](std::size_t n) {
|
||||
typename concur::traits<PC>::context ctx {};
|
||||
for (std::uint32_t i = 1; i <= loop_size; ++i) {
|
||||
std::this_thread::yield();
|
||||
counters[n] = 0;
|
||||
do {
|
||||
ASSERT_TRUE(pc.enqueue(imp::make_span(circ), hdr, ctx, Data{n, i}));
|
||||
std::this_thread::yield();
|
||||
// We need to wait for the consumer to consume the data.
|
||||
} while (counters[n] < nc);
|
||||
if (i % (loop_size / 10) == 0) {
|
||||
log.info("[", n, "] put count: ", i);
|
||||
}
|
||||
}
|
||||
--running;
|
||||
};
|
||||
auto cons_call = [&] {
|
||||
typename concur::traits<PC>::context ctx {};
|
||||
std::array<std::uint64_t, 64> last_i {};
|
||||
for (;;) {
|
||||
std::this_thread::yield();
|
||||
Data v;
|
||||
while (!pc.dequeue(imp::make_span(circ), hdr, ctx, v)) {
|
||||
if (running == 0) return;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
// The v.i variable always increases.
|
||||
if (last_i[v.n] >= v.i) {
|
||||
continue;
|
||||
}
|
||||
last_i[v.n] = v.i;
|
||||
sum += v.i;
|
||||
++counters[v.n];
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::thread> prods(np);
|
||||
for (std::size_t n = 0; n < np; ++n) prods[n] = std::thread(prod_call, n);
|
||||
std::vector<std::thread> conss(nc);
|
||||
for (auto &c : conss) c = std::thread(cons_call);
|
||||
|
||||
for (auto &p : prods) p.join();
|
||||
for (auto &c : conss) c.join();
|
||||
|
||||
EXPECT_EQ(sum, k * np * (loop_size * std::uint64_t(loop_size + 1)) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(concurrent, broadcast) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user