| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 249526c commit aed38a7
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -109,6 +109,9 @@ target_link_libraries(threadpool_cxx14 Threads::Threads) | |||
| 109 | 109 | add_executable(multiple_dispatch example/multiple_dispatch.cpp) | |
| 110 | 110 | target_link_libraries(multiple_dispatch Threads::Threads) | |
| 111 | 111 | ||
| 112 | + add_executable(executor example/executor.cpp) | ||
| 113 | + target_link_libraries(executor Threads::Threads) | ||
| 114 | + | ||
| 112 | 115 | # ----------------------------------------------------------------------------- | |
| 113 | 116 | # Unittest | |
| 114 | 117 | # ----------------------------------------------------------------------------- | |
@@ -122,14 +125,15 @@ set(TF_UTEST_DIR ${PROJECT_SOURCE_DIR}/unittest) | |||
| 122 | 125 | add_executable(taskflow_test_tmp unittest/taskflow.cpp) | |
| 123 | 126 | target_link_libraries(taskflow_test_tmp Threads::Threads) | |
| 124 | 127 | set_target_properties(taskflow_test_tmp PROPERTIES OUTPUT_NAME "taskflow") | |
| 125 | - add_test(builder ${TF_UTEST_DIR}/taskflow -tc=Taskflow.Builder) | ||
| 126 | - add_test(dispatch ${TF_UTEST_DIR}/taskflow -tc=Taskflow.Dispatch) | ||
| 127 | - add_test(parallel_for ${TF_UTEST_DIR}/taskflow -tc=Taskflow.ParallelFor) | ||
| 128 | - add_test(reduce ${TF_UTEST_DIR}/taskflow -tc=Taskflow.Reduce) | ||
| 129 | - add_test(reduce_min ${TF_UTEST_DIR}/taskflow -tc=Taskflow.ReduceMin) | ||
| 130 | - add_test(reduce_max ${TF_UTEST_DIR}/taskflow -tc=Taskflow.ReduceMax) | ||
| 131 | - add_test(joined_subflow ${TF_UTEST_DIR}/taskflow -tc=Taskflow.JoinedSubflow) | ||
| 132 | - add_test(detached_subflow ${TF_UTEST_DIR}/taskflow -tc=Taskflow.DetachedSubflow) | ||
| 128 | + add_test(builder ${TF_UTEST_DIR}/taskflow -tc=Builder) | ||
| 129 | + add_test(dispatch ${TF_UTEST_DIR}/taskflow -tc=Dispatch) | ||
| 130 | + add_test(executor ${TF_UTEST_DIR}/taskflow -tc=Executor) | ||
| 131 | + add_test(parallel_for ${TF_UTEST_DIR}/taskflow -tc=ParallelFor) | ||
| 132 | + add_test(reduce ${TF_UTEST_DIR}/taskflow -tc=Reduce) | ||
| 133 | + add_test(reduce_min ${TF_UTEST_DIR}/taskflow -tc=ReduceMin) | ||
| 134 | + add_test(reduce_max ${TF_UTEST_DIR}/taskflow -tc=ReduceMax) | ||
| 135 | + add_test(joined_subflow ${TF_UTEST_DIR}/taskflow -tc=JoinedSubflow) | ||
| 136 | + add_test(detached_subflow ${TF_UTEST_DIR}/taskflow -tc=DetachedSubflow) | ||
| 133 | 137 | ||
| 134 | 138 | # unittest for threadpool | |
| 135 | 139 | add_executable(threadpool_test_tmp unittest/threadpool.cpp) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,122 @@ | |||
| 1 | + // 2018/10/24 - created by Tsung-Wei Huang | ||
| 2 | + // | ||
| 3 | + // This program demonstrates how to share the executor among different | ||
| 4 | + // taskflow objects to avoid over subcription of threads. | ||
| 5 | + | ||
| 6 | + #include <taskflow/taskflow.hpp> | ||
| 7 | + #include <chrono> | ||
| 8 | + #include <random> | ||
| 9 | + #include <climits> | ||
| 10 | + | ||
| 11 | + // Parameters | ||
| 12 | + size_t MAX_TASKFLOW = 1; | ||
| 13 | + const size_t MAX_COUNT = 4096; | ||
| 14 | + const size_t MAX_THREAD = std::thread::hardware_concurrency(); | ||
| 15 | + | ||
| 16 | + // Procedure | ||
| 17 | + void create_quadruples(tf::Taskflow& tf, std::atomic<int>& c) { | ||
| 18 | + for(size_t i=0; i<MAX_COUNT; ++i) { | ||
| 19 | + auto [A, B, C, D] = tf.silent_emplace( | ||
| 20 | + [&] () { c.fetch_add(1, std::memory_order_relaxed); }, | ||
| 21 | + [&] () { c.fetch_add(1, std::memory_order_relaxed); }, | ||
| 22 | + [&] () { c.fetch_add(1, std::memory_order_relaxed); }, | ||
| 23 | + [&] () { c.fetch_add(1, std::memory_order_relaxed); } | ||
| 24 | + ); | ||
| 25 | + A.precede(B); | ||
| 26 | + A.precede(C); | ||
| 27 | + C.precede(D); | ||
| 28 | + B.precede(D); | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + // Function: unique_executor | ||
| 33 | + auto unique_executor() { | ||
| 34 | + | ||
| 35 | + auto beg = std::chrono::high_resolution_clock::now(); | ||
| 36 | + | ||
| 37 | + std::atomic<int> counter {0}; | ||
| 38 | + std::list<tf::Taskflow> tfs; | ||
| 39 | + | ||
| 40 | + for(size_t i=0; i<MAX_TASKFLOW; ++i) { | ||
| 41 | + auto& tf = tfs.emplace_back(MAX_THREAD); | ||
| 42 | + create_quadruples(tf, counter); | ||
| 43 | + assert(tf.share_executor().use_count() == 2); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + std::vector<std::shared_future<void>> futures; | ||
| 47 | + for(auto& tf : tfs) { | ||
| 48 | + futures.emplace_back(tf.dispatch()); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + for(auto& fu : futures) { | ||
| 52 | + fu.get(); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + assert(counter == MAX_TASKFLOW*MAX_COUNT*4); | ||
| 56 | + | ||
| 57 | + auto end = std::chrono::high_resolution_clock::now(); | ||
| 58 | + return std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + // Function: shared_executor | ||
| 62 | + auto shared_executor() { | ||
| 63 | + | ||
| 64 | + auto beg = std::chrono::high_resolution_clock::now(); | ||
| 65 | + | ||
| 66 | + std::atomic<int> counter {0}; | ||
| 67 | + std::list<tf::Taskflow> tfs; | ||
| 68 | + | ||
| 69 | + auto executor = std::make_shared<tf::Taskflow::Executor>(MAX_THREAD); | ||
| 70 | + | ||
| 71 | + for(size_t i=0; i<MAX_TASKFLOW; ++i) { | ||
| 72 | + assert(executor.use_count() == i + 1); | ||
| 73 | + auto& tf = tfs.emplace_back(executor); | ||
| 74 | + create_quadruples(tf, counter); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + std::vector<std::shared_future<void>> futures; | ||
| 78 | + for(auto& tf : tfs) { | ||
| 79 | + futures.emplace_back(tf.dispatch()); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + for(auto& fu : futures) { | ||
| 83 | + fu.get(); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + assert(counter == MAX_TASKFLOW*MAX_COUNT*4); | ||
| 87 | + | ||
| 88 | + auto end = std::chrono::high_resolution_clock::now(); | ||
| 89 | + return std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count(); | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + // ---------------------------------------------------------------------------- | ||
| 93 | + | ||
| 94 | + // Function: main | ||
| 95 | + int main(int argc, char* argv[]) { | ||
| 96 | + | ||
| 97 | + const size_t width = 12; | ||
| 98 | + | ||
| 99 | + std::cout << std::setw(width) << "# taskflows" | ||
| 100 | + << std::setw(width) << "shared (ms)" | ||
| 101 | + << std::setw(width) << "unique (ms)" | ||
| 102 | + << std::endl; | ||
| 103 | + | ||
| 104 | + for(MAX_TASKFLOW=1; MAX_TASKFLOW<=128; MAX_TASKFLOW *= 2) { | ||
| 105 | + | ||
| 106 | + auto s = shared_executor(); | ||
| 107 | + auto u = unique_executor(); | ||
| 108 | + | ||
| 109 | + std::cout << std::setw(width) << MAX_TASKFLOW | ||
| 110 | + << std::setw(width) << s | ||
| 111 | + << std::setw(width) << u | ||
| 112 | + << std::endl; | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + | ||
| 116 | + | ||
| 117 | + | ||
| 118 | + return 0; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + | ||
| 122 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,7 @@ | |||
| 1 | + // 2018/10/24 - modified by Tsung-Wei Huang | ||
| 2 | + // - Taskflow is templated at threadpool | ||
| 3 | + // - added graph-level comparison with different thread pools | ||
| 4 | + // | ||
| 1 | 5 | // 2018/09/19 - created by Tsung-Wei Huang | |
| 2 | 6 | // | |
| 3 | 7 | // This program is used to benchmark the taskflow under different types | |
| Back | FazBrowse Home | New Git URL |
0 commit comments