libcruft-util/test/parallel/spmc.cpp

73 lines
1.5 KiB
C++
Raw Normal View History

#include "parallel/spmc.hpp"
#include "job/flag.hpp"
#include "debug.hpp"
#include <algorithm>
#include <thread>
#include <iostream>
static constexpr uint32_t slots = 4;
static constexpr int parallelism = 15;
static constexpr int chunk_size = 1<<16;
util::job::flag start;
using queue_t = util::parallel::spmc<int,slots>;
///////////////////////////////////////////////////////////////////////////////
void transfer (queue_t &src, std::vector<int> &dst)
{
(void)dst;
start.wait ();
int last;
for (int i = 0; i < chunk_size; ++i) {
while (!src.pop (last))
;
dst[i] = last;
}
}
///////////////////////////////////////////////////////////////////////////////
int
main ()
{
queue_t src;
std::vector<std::vector<int>> dst (parallelism + 1);
std::vector<std::thread> workers;
for (int i = 0; i < parallelism; ++i) {
dst[i].resize (chunk_size);
workers.emplace_back (transfer, std::ref (src), std::ref (dst[i]));
}
start.notify ();
for (int i = 0; i < parallelism * chunk_size; ++i) {
while (!src.push (i))
;
}
for (auto &t: workers)
t.join ();
std::vector<int> tally;
for (auto &d: dst)
tally.insert (tally.end (), d.begin (), d.end ());
std::sort (tally.begin (), tally.end ());
int missing = 0;
for (int i = 0; i < parallelism * chunk_size; ++i)
if (tally[i] != i)
++missing;
std::clog << "missing: " << missing << '\n';
return 0;
}