I have a function that just prints thread id it is called from. I want 2 threads call this function taking turns n times. I had implemented this functionality in pthreads with a condition variable but it is too verbose. What I want program to print as follows:
id: 0
id: 1
id: 0
id: 1
id: 0
id: 1
...
In the end, "id: 0" and "id: 1" should be printed n times.
What is the idiomatic way of doing this OpenMP?
CodePudding user response:
You can check the thread number against your iteration count and implement the handoff with a barrier.
#include <omp.h>
#include <cstdio>
int main()
{
/* note that it is not pragma omp parallel for, just a parallel block */
# pragma omp parallel num_threads(2)
for(int i = 0; i < 10; i) {
if((i & 1) == (omp_get_thread_num() & 1))
std::printf("%d: thread %d\n", i, omp_get_thread_num());
# pragma omp barrier
}
}
CodePudding user response:
Since the OP has mentioned that this is for benchmarking cross-core latency, a purely std::atomic
-based solution should probably be at least considered.
Using C 20's wait()
, we can do the following:
#include <thread>
#include <atomic>
#include <iostream>
std::atomic<int> target(1);
void worker(int wid, int n) {
int v = wid;
for (int i = 0; i < n; i) {
target.wait(v);
v = target.load() 1;
target.store(v);
target.notify_one();
// std::cout << wid;
}
}
int main() {
int n = 100;
std::jthread t0(worker, 0, n);
std::jthread t1(worker, 1, n);
}
Admittedly, this is a bit by-the-seat-of-your-pants during bootstrapping. So here's what's going on:
t0
's firstwait()
will immediately pass, since0 != 1
, and nothing can changetarget
beforehand.t1
's firstwait()
, won't proceed untilt0
movestarget
away from its initial value: 1.- If
t0
performs itsnotify_one()
beforet1
reaches itswait()
, thent1
's wait won't block sincetarget
is already 2 by then.
After that, both thread always wait()
for the value to change from the one they have set, which will cause them to alternate.
Obviously, this only works for 2 threads.