Reputation: 11920
I'm using a local function definition to run a code block N times acting like a parallel-for version of C# but it gives multiple definition error for f
function when I use two or more of it in same scope. How can I make the function name incrementally changed such as f1,f2,f3,.. after each usage in same scope?
Definition:
#ifndef PARALLEL_FOR
#define PARALLEL_FOR(N,O) \
struct LocalClass \
{ \
void operator()(int i) const O \
} f; \
std::thread threads[N]; \
for(int loopCounterI=0; loopCounterI<N; loopCounterI++) \
{ \
threads[loopCounterI]=std::thread(f,loopCounterI); \
} \
for(int loopCounterI=0; loopCounterI<N; loopCounterI++) \
{ \
threads[loopCounterI].join(); \
} \
#endif
Usage:
PARALLEL_FOR(
5,
{std::cout<<100*i<<std::endl;}
);
output:
0
300
200
100
400
normally adding {\
and }\
would solve for consequent calls but what if I do nested parallel for?
Upvotes: 0
Views: 447
Reputation: 3849
Instead of passing a unique ID, you could use __LINE__
.
But instead of an ugly macro, why don't you use a function with a lambda?
template <int N, class F>
void parallel_for(F f) {
std::thread threads[N]; // or std::array<std::thread, N> threads;
for(int loopCounterI=0; loopCounterI<N; loopCounterI++) {
threads[loopCounterI]=std::thread(f,loopCounterI);
}
for(int loopCounterI=0; loopCounterI<N; loopCounterI++) {
threads[loopCounterI].join();
}
}
Used like this:
parallel_for<5>([] (int i) {
std::cout<<100*i<<std::endl;
});
The lambda can capture the variables you need:
int j = ...;
parallel_for<5>([j] (int i) {
std::cout<<100*(i+j)<<std::endl;
});
Upvotes: 5
Reputation: 651
Although it doesn't seem like the ideal solution to me, you can concatenate strings in macros using ##
. In your code do the following
#ifndef PARALLEL_FOR
#define PARALLEL_FOR(N,O,usageInd) \
struct LocalClass##usageInd \
{ \
void operator()(int i) const O \
} f##usageInd; \
std::thread threads[N]; \
for(int loopCounterI=0; loopCounterI<N; loopCounterI++) \
{ \
threads[loopCounterI]=std::thread(f##usageInd,loopCounterI); \
} \
for(int loopCounterI=0; loopCounterI<N; loopCounterI++) \
{ \
threads[loopCounterI].join(); \
} \
#endif
It would be up to you to now pass an index for each usage.
Upvotes: 2