- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a function foo() and would like to run multiple instances of foo() in a single task. Sometimes it will be 3 foo() instances and at other times it may be 6 instances, or 8, or 9. It is not known in advance how many instances of foo() to run in a single task.
Each instance of foo() also needs to have its arguments be passed by value.
Is this possible to do with TBB?
Basically, I would like to group several functions together and run them in a single task. And, then I would like to do it again and again, with different number of functions per each task to be run in parallel. The functions are actually the same, but with different argument values.
Thank you,
-Victor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something like this (modified previous version to hopefully better reflect what you are asking, lines 22-26)?
#include <iostream>
#include <tbb/task_group.h>
#include <vector>
#include <functional>
void foo(int arg) {
std::cout << "arg = " << arg << std::endl;
}
int main() {
tbb::task_group g;
// Create a vector of function calls
std::vector<std::function<void()>> function_bundles;
// Populate the vector with function calls
function_bundles.push_back([] { foo(1); });
function_bundles.push_back([] { foo(2); });
// Add more function calls as needed
// Run all function calls as a single task
g.run([&function_bundles] {
for (const auto& func : function_bundles) {
func(); // Execute the function
}
});
g.wait(); // Wait for all tasks to finish
}
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
does this help:
#include <iostream>
#include <tbb/task_group.h>
void foo(int arg) {
std::cout << "arg = " << arg << std::endl;
}
int main() {
tbb::task_group g;
// args is a vector of arguments you want to pass by value
std::vector<int> args = { 1, 2, 3, 4, 5 };
for (int arg : args) {
g.run([=] { foo(arg); }); // Capture arg by value
}
g.wait(); // Wait for all tasks to finish
}
}
For more in-depth regarding task_group: migrating to task_group
For example of using task_group: task_group sample
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Mark. I use task groups in the above way already and they are great for one function to one task mapping.
How would you pass two or more calls (dynamically determined how many calls) to a single g.run([=]) instance, with each call to foo() with its own arguments?
Basically, this would be a method of running a bundle/vector/list of function calls by a single task. This comes up in cases where there are many instances of a function are used, but each instance is too small to be processed efficiently in parallel on its own, so it would be more efficient to bundle several small instances and have one worker/task run each bundle.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something like this (modified previous version to hopefully better reflect what you are asking, lines 22-26)?
#include <iostream>
#include <tbb/task_group.h>
#include <vector>
#include <functional>
void foo(int arg) {
std::cout << "arg = " << arg << std::endl;
}
int main() {
tbb::task_group g;
// Create a vector of function calls
std::vector<std::function<void()>> function_bundles;
// Populate the vector with function calls
function_bundles.push_back([] { foo(1); });
function_bundles.push_back([] { foo(2); });
// Add more function calls as needed
// Run all function calls as a single task
g.run([&function_bundles] {
for (const auto& func : function_bundles) {
func(); // Execute the function
}
});
g.wait(); // Wait for all tasks to finish
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Mark. The above implementation is fabulous and is much more advanced than one I came up with. It supports any "foo" function, and even supports multiple functions (such as foo and bar) to be used, each with its own arguments, and any kinds of arguments. Pretty amazing!
One thing that I changed in my usage is using pass by value instead of reference, since I'm creating many bundles. This creates a copy of the bundle for each task. Sadly, it's an additional overhead, and maybe an improvement that can be made.
I added this code, with credit, to a recent blog about this topic (https://duvanenko.tech.blog/2024/04/15/parallel-pattern-of-bundling-small-work-items/) - still in the works.
Thank you for your help! This solution will definitely be used.
-Victor
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page