| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1442c23 commit dea5a35
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -261,6 +261,7 @@ add_test(builder ${TF_UTEST_DIR}/taskflow -tc=Builder) | |||
| 261 | 261 | add_test(creation ${TF_UTEST_DIR}/taskflow -tc=Creation) | |
| 262 | 262 | add_test(dispatch ${TF_UTEST_DIR}/taskflow -tc=Dispatch) | |
| 263 | 263 | add_test(multiple_runs ${TF_UTEST_DIR}/taskflow -tc=MultipleRuns) | |
| 264 | + add_test(parallel_runs ${TF_UTEST_DIR}/taskflow -tc=ParallelRuns) | ||
| 264 | 265 | add_test(parallel_for ${TF_UTEST_DIR}/taskflow -tc=ParallelFor) | |
| 265 | 266 | add_test(parallel_for_idx ${TF_UTEST_DIR}/taskflow -tc=ParallelForOnIndex) | |
| 266 | 267 | add_test(reduce ${TF_UTEST_DIR}/taskflow -tc=Reduce) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -216,6 +216,7 @@ The executor provides a rich set of methods to run a taskflow. | |||
| 216 | 216 | You can run a taskflow one or multiple times, or until a stopping criteria is met. | |
| 217 | 217 | These methods are non-blocking and all return a [std::future][std::future] | |
| 218 | 218 | to let you query the execution status. | |
| 219 | + All methods are *thread-safe*. | ||
| 219 | 220 | ||
| 220 | 221 | ```cpp | |
| 221 | 222 | executor.run(taskflow); // run the taskflow once | |
@@ -527,7 +528,7 @@ tf::Task B = taskflow.emplace([] (tf::Subflow& subflow) { | |||
| 527 | 528 | ||
| 528 | 529 | A.precede(B); | |
| 529 | 530 | ||
| 530 | - executor.run(tf).get(); // run the taskflow | ||
| 531 | + executor.run(tf).wait(); // run the taskflow | ||
| 531 | 532 | tf.dump(std::cout); // dump the graph including dynamic tasks | |
| 532 | 533 | ``` | |
| 533 | 534 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,6 +19,7 @@ To download the newest version of Cpp-Taskflow, please clone from <a href="https | |||
| 19 | 19 | @li Discovering a scalable memory allocator to handle the taskflow graph | |
| 20 | 20 | @li Adding more benchmarks to compare Cpp-Taskflow with OpenMP and TBB | |
| 21 | 21 | @li Improving the partition policy of parallel_for | |
| 22 | + @li Making executor thread-safe | ||
| 22 | 23 | ||
| 23 | 24 | @section master-branch_bug_fixes Bug Fixes | |
| 24 | 25 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,6 @@ | |||
| 1 | + // 2019/08/03 - modified by Tsung-Wei Huang | ||
| 2 | + // - made executor thread-safe | ||
| 3 | + // | ||
| 1 | 4 | // 2019/07/26 - modified by Chun-Xun Lin | |
| 2 | 5 | // - Combine explore_task & wait_for_task | |
| 3 | 6 | // - Remove CAS operations | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -420,39 +420,67 @@ TEST_CASE("MultipleRuns" * doctest::timeout(300)) { | |||
| 420 | 420 | // Testcase: ParallelRuns | |
| 421 | 421 | // -------------------------------------------------------- | |
| 422 | 422 | TEST_CASE("ParallelRuns" * doctest::timeout(300)) { | |
| 423 | - | ||
| 424 | - for(size_t w=0; w<=32; ++w) { | ||
| 425 | - | ||
| 426 | - tf::Executor executor(w); | ||
| 427 | 423 | ||
| 428 | - std::atomic<int> counter = 0; | ||
| 424 | + std::atomic<int> counter; | ||
| 425 | + std::vector<std::thread> threads; | ||
| 429 | 426 | ||
| 430 | - auto make_taskflow = [&] (tf::Taskflow& tf) { | ||
| 431 | - for(int i=0; i<1024; i++) { | ||
| 432 | - auto A = tf.emplace([&] () { | ||
| 433 | - counter.fetch_add(1, std::memory_order_relaxed); | ||
| 434 | - }); | ||
| 435 | - auto B = tf.emplace([&] () { | ||
| 436 | - counter.fetch_add(1, std::memory_order_relaxed); | ||
| 437 | - }); | ||
| 438 | - A.precede(B); | ||
| 439 | - } | ||
| 440 | - }; | ||
| 441 | - | ||
| 442 | - std::vector<std::thread> threads; | ||
| 443 | - for(int t=1; t<=32; t++) { | ||
| 444 | - threads.emplace_back([&] () { | ||
| 445 | - tf::Taskflow taskflow; | ||
| 446 | - make_taskflow(taskflow); | ||
| 447 | - executor.run(taskflow).wait(); | ||
| 427 | + auto make_taskflow = [&] (tf::Taskflow& tf) { | ||
| 428 | + for(int i=0; i<1024; i++) { | ||
| 429 | + auto A = tf.emplace([&] () { | ||
| 430 | + counter.fetch_add(1, std::memory_order_relaxed); | ||
| 448 | 431 | }); | |
| 432 | + auto B = tf.emplace([&] () { | ||
| 433 | + counter.fetch_add(1, std::memory_order_relaxed); | ||
| 434 | + }); | ||
| 435 | + A.precede(B); | ||
| 449 | 436 | } | |
| 437 | + }; | ||
| 450 | 438 | ||
| 451 | - for(auto& t : threads) { | ||
| 452 | - t.join(); | ||
| 453 | - } | ||
| 439 | + SUBCASE("RunAndWait") { | ||
| 440 | + for(size_t w=0; w<=32; ++w) { | ||
| 441 | + tf::Executor executor(w); | ||
| 442 | + counter = 0; | ||
| 443 | + for(int t=0; t<32; t++) { | ||
| 444 | + threads.emplace_back([&] () { | ||
| 445 | + tf::Taskflow taskflow; | ||
| 446 | + make_taskflow(taskflow); | ||
| 447 | + executor.run(taskflow).wait(); | ||
| 448 | + }); | ||
| 449 | + } | ||
| 454 | 450 | ||
| 455 | - REQUIRE(counter.load() == 32*1024*2); | ||
| 451 | + for(auto& t : threads) { | ||
| 452 | + t.join(); | ||
| 453 | + } | ||
| 454 | + threads.clear(); | ||
| 455 | + | ||
| 456 | + REQUIRE(counter.load() == 32*1024*2); | ||
| 457 | + } | ||
| 458 | + } | ||
| 459 | + | ||
| 460 | + SUBCASE("RunAndWaitForAll") { | ||
| 461 | + for(size_t w=0; w<=32; ++w) { | ||
| 462 | + tf::Executor executor(w); | ||
| 463 | + counter = 0; | ||
| 464 | + std::vector<std::unique_ptr<tf::Taskflow>> taskflows(32); | ||
| 465 | + std::atomic<size_t> barrier(0); | ||
| 466 | + for(int t=0; t<32; t++) { | ||
| 467 | + threads.emplace_back([&, t=t] () { | ||
| 468 | + taskflows[t] = std::make_unique<tf::Taskflow>(); | ||
| 469 | + make_taskflow(*taskflows[t]); | ||
| 470 | + executor.run(*taskflows[t]); | ||
| 471 | + ++barrier; // make sure all runs are issued | ||
| 472 | + }); | ||
| 473 | + } | ||
| 474 | + | ||
| 475 | + while(barrier != 32); | ||
| 476 | + executor.wait_for_all(); | ||
| 477 | + REQUIRE(counter.load() == 32*1024*2); | ||
| 478 | + | ||
| 479 | + for(auto& t : threads) { | ||
| 480 | + t.join(); | ||
| 481 | + } | ||
| 482 | + threads.clear(); | ||
| 483 | + } | ||
| 456 | 484 | } | |
| 457 | 485 | ||
| 458 | 486 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments