Files
FluidSimCpp/tools/thread_benchmark.cpp
2026-10-23 03:00:20 +02:00

72 lines
3.0 KiB
C++

#include "FluidSim/Fluid.hpp"
#include "FluidSim/Scenario.hpp"
#include "FluidSim/TwoStrokeScenario.hpp"
#include "FluidSim/HelmholtzScenario.hpp"
#include "FluidSim/PulseTestScenario.hpp"
#include <barrier>
#include <chrono>
#include <iostream>
#include <thread>
using namespace fluidsim::port;
int main() {
for (std::string name : {"twin", "turbo", "b205", "two-stroke-racing", "two-stroke-straight", "helmholtz", "pulse", "large"}) {
std::vector<Pipe1D> geometry;
if (name == "large") {
for (int i=0; i<64; ++i) geometry.emplace_back(.001f, 2, 256);
} else if (name == "helmholtz") {
HelmholtzScenario s; geometry.push_back(s.neck());
} else if (name == "pulse") {
PulseTestScenario s; geometry.push_back(s.pipe());
} else if (name.starts_with("two-stroke")) {
TwoStrokeConfig config;
config.exhaust = name == "two-stroke-straight" ? TwoStrokeExhaust::Straight : TwoStrokeExhaust::Racing;
TwoStrokeScenario s(44100, config); geometry = s.pipes;
} else {
FourStrokeScenario s(44100, name == "b205" ? FourStrokePreset::SaabB205 : FourStrokePreset::Twin, name == "turbo");
geometry = s.pipes;
}
const int steps = 4000;
for (int workers : {1, 2, 4}) {
auto p = geometry;
auto advance = [&](int worker) {
for (int k = worker; k < static_cast<int>(p.size()); k += workers) {
auto &a = p[k];
auto l = a.state(0), r = a.state(static_cast<int>(a.cells.size()) - 1);
l.velocity = -l.velocity;
r.velocity = -r.velocity;
a.left_ghost = l;
a.right_ghost = r;
a.advance(.0000005f);
}
};
std::barrier sync(workers + 1);
std::vector<std::jthread> pool;
if (workers > 1)
for (int k = 0; k < workers; k++)
pool.emplace_back([&, k] {
for (int i = 0; i < steps; i++) {
sync.arrive_and_wait();
advance(k);
sync.arrive_and_wait();
}
});
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < steps; i++) {
if (workers == 1)
advance(0);
else {
sync.arrive_and_wait();
sync.arrive_and_wait();
}
}
double sec = std::chrono::duration<double>(std::chrono::steady_clock::now() - start).count();
pool.clear();
double sum = 0;
for (auto &q : p)
sum += q.state(0).pressure;
std::cout << "scenario=" << name << " pipes=" << p.size() << " workers=" << workers
<< " steps=" << steps << " seconds=" << sec << " checksum=" << sum << '\n';
}
}
}