diff --git a/app/playground/main.cpp b/app/playground/main.cpp index 5d417c7..4d585cd 100644 --- a/app/playground/main.cpp +++ b/app/playground/main.cpp @@ -12,7 +12,7 @@ using namespace pls; // Example for static memory allocation (no malloc or free required) static static_scheduler_memory<8, 2 << 12> my_scheduler_memory; -class fib: public tbb_sub_task { +class fib: public fork_join_sub_task { static constexpr int CUTOFF = 20; int num_; @@ -64,7 +64,7 @@ int main() { int result; fib fib_sub_task{45, &result}; - tbb_task tbb_task{&fib_sub_task, task_id{1}}; + fork_join_task tbb_task{&fib_sub_task, task_id{1}}; scheduler::execute_task(tbb_task); std::cout << "Result: " << result << std::endl; diff --git a/lib/pls/CMakeLists.txt b/lib/pls/CMakeLists.txt index bad2b80..ff6fe7e 100644 --- a/lib/pls/CMakeLists.txt +++ b/lib/pls/CMakeLists.txt @@ -12,8 +12,9 @@ add_library(pls STATIC src/internal/base/aligned_stack.cpp include/pls/internal/base/aligned_stack.h include/pls/internal/base/system_details.h src/internal/scheduling/run_on_n_threads_task.cpp include/pls/internal/scheduling/run_on_n_threads_task.h - src/internal/scheduling/tbb_task.cpp include/pls/internal/scheduling/tbb_task.h - src/internal/base/deque.cpp include/pls/internal/base/deque.h) + src/internal/scheduling/fork_join_task.cpp include/pls/internal/scheduling/fork_join_task.h + src/internal/base/deque.cpp include/pls/internal/base/deque.h + src/algorithms/invoke_parallel.cpp include/pls/algorithms/invoke_parallel.h) # Add everything in `./include` to be in the include path of this project target_include_directories(pls diff --git a/lib/pls/include/pls/algorithms/invoke_parallel.h b/lib/pls/include/pls/algorithms/invoke_parallel.h new file mode 100644 index 0000000..3809034 --- /dev/null +++ b/lib/pls/include/pls/algorithms/invoke_parallel.h @@ -0,0 +1,16 @@ + +#ifndef PLS_PARALLEL_INVOKE_H +#define PLS_PARALLEL_INVOKE_H + +namespace pls { + namespace algorithm { +// template +// void invoke_parallel(Function1 function1, Function2 function2) { +// if (already_this_invoke_parallel_instance) { +// +// } +// } + } +} + +#endif //PLS_PARALLEL_INVOKE_H diff --git a/lib/pls/include/pls/internal/scheduling/tbb_task.h b/lib/pls/include/pls/internal/scheduling/fork_join_task.h similarity index 76% rename from lib/pls/include/pls/internal/scheduling/tbb_task.h rename to lib/pls/include/pls/internal/scheduling/fork_join_task.h index d3284b6..eb08fcd 100644 --- a/lib/pls/include/pls/internal/scheduling/tbb_task.h +++ b/lib/pls/include/pls/internal/scheduling/fork_join_task.h @@ -11,22 +11,22 @@ namespace pls { namespace internal { namespace scheduling { - class tbb_task; - class tbb_sub_task: public base::deque_item { - friend class tbb_task; + class fork_join_task; + class fork_join_sub_task: public base::deque_item { + friend class fork_join_task; // Coordinate finishing of sub_tasks std::atomic_uint32_t ref_count_; - tbb_sub_task* parent_; + fork_join_sub_task* parent_; // Access to TBB scheduling environment - tbb_task* tbb_task_; + fork_join_task* tbb_task_; // Stack Management (reset stack pointer after wait_for_all() calls) base::aligned_stack::state stack_state_; protected: - explicit tbb_sub_task(); - tbb_sub_task(const tbb_sub_task& other); + explicit fork_join_sub_task(); + fork_join_sub_task(const fork_join_sub_task& other); virtual void execute_internal() = 0; // SubClass Implementations: @@ -42,7 +42,7 @@ namespace pls { void spawn_child(const T& sub_task); void wait_for_all(); private: - void spawn_child_internal(tbb_sub_task* sub_task); + void spawn_child_internal(fork_join_sub_task* sub_task); void execute(); public: @@ -51,26 +51,26 @@ namespace pls { } }; - class tbb_task: public abstract_task { - friend class tbb_sub_task; + class fork_join_task: public abstract_task { + friend class fork_join_sub_task; - tbb_sub_task* root_task_; + fork_join_sub_task* root_task_; base::aligned_stack* my_stack_; // Double-Ended Queue management - base::deque deque_; + base::deque deque_; // Steal Management - tbb_sub_task* last_stolen_; + fork_join_sub_task* last_stolen_; - tbb_sub_task* get_local_sub_task(); - tbb_sub_task* get_stolen_sub_task(); + fork_join_sub_task* get_local_sub_task(); + fork_join_sub_task* get_stolen_sub_task(); bool internal_stealing(abstract_task* other_task) override; bool split_task(base::spin_lock* /*lock*/) override; public: - explicit tbb_task(tbb_sub_task* root_task, const abstract_task::id& id): + explicit fork_join_task(fork_join_sub_task* root_task, const abstract_task::id& id): abstract_task{0, id}, root_task_{root_task}, my_stack_{nullptr}, @@ -89,8 +89,8 @@ namespace pls { }; template - void tbb_sub_task::spawn_child(const T& task) { - static_assert(std::is_base_of::value, "Only pass tbb_sub_task subclasses!"); + void fork_join_sub_task::spawn_child(const T& task) { + static_assert(std::is_base_of::value, "Only pass fork_join_sub_task subclasses!"); T* new_task = tbb_task_->my_stack_->push(task); spawn_child_internal(new_task); diff --git a/lib/pls/include/pls/pls.h b/lib/pls/include/pls/pls.h index 7b81a9c..6b7f81b 100644 --- a/lib/pls/include/pls/pls.h +++ b/lib/pls/include/pls/pls.h @@ -2,7 +2,7 @@ #define PLS_LIBRARY_H #include "pls/internal/scheduling/scheduler.h" -#include "pls/internal/scheduling/tbb_task.h" +#include "pls/internal/scheduling/fork_join_task.h" #include "pls/internal/scheduling/abstract_task.h" namespace pls { @@ -10,8 +10,8 @@ namespace pls { using internal::scheduling::static_scheduler_memory; using task_id = internal::scheduling::abstract_task::id; - using internal::scheduling::tbb_sub_task; - using internal::scheduling::tbb_task; + using internal::scheduling::fork_join_sub_task; + using internal::scheduling::fork_join_task; } #endif diff --git a/lib/pls/src/algorithms/invoke_parallel.cpp b/lib/pls/src/algorithms/invoke_parallel.cpp new file mode 100644 index 0000000..598d59f --- /dev/null +++ b/lib/pls/src/algorithms/invoke_parallel.cpp @@ -0,0 +1 @@ +#include "pls/algorithms/invoke_parallel.h" diff --git a/lib/pls/src/internal/scheduling/tbb_task.cpp b/lib/pls/src/internal/scheduling/fork_join_task.cpp similarity index 79% rename from lib/pls/src/internal/scheduling/tbb_task.cpp rename to lib/pls/src/internal/scheduling/fork_join_task.cpp index 2a6024d..cf16d53 100644 --- a/lib/pls/src/internal/scheduling/tbb_task.cpp +++ b/lib/pls/src/internal/scheduling/fork_join_task.cpp @@ -1,21 +1,21 @@ #include "pls/internal/scheduling/scheduler.h" -#include "pls/internal/scheduling/tbb_task.h" +#include "pls/internal/scheduling/fork_join_task.h" namespace pls { namespace internal { namespace scheduling { - tbb_sub_task::tbb_sub_task(): + fork_join_sub_task::fork_join_sub_task(): base::deque_item{}, ref_count_{0}, parent_{nullptr}, tbb_task_{nullptr}, stack_state_{nullptr} {} - tbb_sub_task::tbb_sub_task(const tbb_sub_task& other): base::deque_item(other) { + fork_join_sub_task::fork_join_sub_task(const fork_join_sub_task& other): base::deque_item(other) { // Do Nothing, will be inited after this anyways } - void tbb_sub_task::execute() { + void fork_join_sub_task::execute() { execute_internal(); wait_for_all(); @@ -24,7 +24,7 @@ namespace pls { } } - void tbb_sub_task::spawn_child_internal(tbb_sub_task* sub_task) { + void fork_join_sub_task::spawn_child_internal(fork_join_sub_task* sub_task) { // Keep our refcount up to date ref_count_++; @@ -36,9 +36,9 @@ namespace pls { tbb_task_->deque_.push_tail(sub_task); } - void tbb_sub_task::wait_for_all() { + void fork_join_sub_task::wait_for_all() { while (ref_count_ > 0) { - tbb_sub_task* local_task = tbb_task_->get_local_sub_task(); + fork_join_sub_task* local_task = tbb_task_->get_local_sub_task(); if (local_task != nullptr) { local_task->execute(); } else { @@ -52,22 +52,22 @@ namespace pls { tbb_task_->my_stack_->reset_state(stack_state_); } - tbb_sub_task* tbb_task::get_local_sub_task() { + fork_join_sub_task* fork_join_task::get_local_sub_task() { return deque_.pop_tail(); } - tbb_sub_task* tbb_task::get_stolen_sub_task() { + fork_join_sub_task* fork_join_task::get_stolen_sub_task() { return deque_.pop_head(); } - bool tbb_task::internal_stealing(abstract_task* other_task) { - auto cast_other_task = reinterpret_cast(other_task); + bool fork_join_task::internal_stealing(abstract_task* other_task) { + auto cast_other_task = reinterpret_cast(other_task); auto stolen_sub_task = cast_other_task->get_stolen_sub_task(); if (stolen_sub_task == nullptr) { return false; } else { - // Make sub-task belong to our tbb_task instance + // Make sub-task belong to our fork_join_task instance stolen_sub_task->tbb_task_ = this; stolen_sub_task->stack_state_ = my_stack_->save_state(); // We will execute this next without explicitly moving it onto our stack storage @@ -77,12 +77,12 @@ namespace pls { } } - bool tbb_task::split_task(base::spin_lock* lock) { - tbb_sub_task* stolen_sub_task = get_stolen_sub_task(); + bool fork_join_task::split_task(base::spin_lock* lock) { + fork_join_sub_task* stolen_sub_task = get_stolen_sub_task(); if (stolen_sub_task == nullptr) { return false; } - tbb_task task{stolen_sub_task, this->unique_id()}; + fork_join_task task{stolen_sub_task, this->unique_id()}; // In success case, unlock. // TODO: this locking is complicated and error prone. diff --git a/test/scheduling_tests.cpp b/test/scheduling_tests.cpp index 47ff5e2..50f208e 100644 --- a/test/scheduling_tests.cpp +++ b/test/scheduling_tests.cpp @@ -4,7 +4,7 @@ using namespace pls; -class once_sub_task: public tbb_sub_task { +class once_sub_task: public fork_join_sub_task { std::atomic* counter_; int children_; @@ -18,12 +18,12 @@ protected: public: explicit once_sub_task(std::atomic* counter, int children): - tbb_sub_task(), + fork_join_sub_task(), counter_{counter}, children_{children} {} }; -class force_steal_sub_task: public tbb_sub_task { +class force_steal_sub_task: public fork_join_sub_task { std::atomic* parent_counter_; std::atomic* overall_counter_; @@ -42,12 +42,12 @@ protected: public: explicit force_steal_sub_task(std::atomic* parent_counter, std::atomic* overall_counter): - tbb_sub_task(), + fork_join_sub_task(), parent_counter_{parent_counter}, overall_counter_{overall_counter} {} }; -TEST_CASE( "tbb task are scheduled correctly", "[internal/scheduling/tbb_task.h]") { +TEST_CASE( "tbb task are scheduled correctly", "[internal/scheduling/fork_join_task.h]") { static static_scheduler_memory<8, 2 << 12> my_scheduler_memory; SECTION("tasks are executed exactly once") { @@ -58,7 +58,7 @@ TEST_CASE( "tbb task are scheduled correctly", "[internal/scheduling/tbb_task.h] my_scheduler.perform_work([&] (){ once_sub_task sub_task{&counter, start_counter}; - tbb_task task{&sub_task}; + fork_join_task task{&sub_task}; scheduler::execute_task(task); }); @@ -71,7 +71,7 @@ TEST_CASE( "tbb task are scheduled correctly", "[internal/scheduling/tbb_task.h] my_scheduler.perform_work([&] (){ std::atomic dummy_parent{1}, overall_counter{8}; force_steal_sub_task sub_task{&dummy_parent, &overall_counter}; - tbb_task task{&sub_task}; + fork_join_task task{&sub_task}; scheduler::execute_task(task); }); my_scheduler.terminate(true);