-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Enhancement] generalize tbb's thread_pool_base (#1403)
* Copy implementation of thread_pool_base. Inorder to use later the thread_pool_base we need to separate it from tbb * Rename tbbexec to execpools The goal is to have a common space for all the thread pools that depends on 3rd party threading libraries, like tbb. The new name is execpools like execution pools, where all thread pools are collected. tbb subdirectory is about separating the different implementation files to manage easily the library dependencies. * Create task flow pool implementation. The goal is to see that the task_pool_base abstraction is sufficient or not. * Add boost thread pool implementation * Add Standalone implementation for Asio. The idea is that let's have an asio thread pool rather then a boost. In this way the standalone asio can be also used as an implementation. Which implementation is used for Asio is controlled by the cmake parameter STDEXEC_ASIO_IMPLEMENTATION. It can be 'boost' or 'standalone'. Cmake generates a configuration file that creates a namespace: execpools::asio_impl. This points to the corresponding implementation. In this way the pool implementation is referenced only to this namespace. The configuration file is generated into the build directory, inorder to not pollute the source tree with generated files. --------- Co-authored-by: David Eles <eles.david88@gmail.com> Co-authored-by: Eric Niebler <eniebler@nvidia.com>
- Loading branch information
1 parent
3e41a95
commit 4d8d194
Showing
20 changed files
with
1,361 additions
and
549 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# - This function imports the standalone version of ASIO | ||
# | ||
# Importing standalone asio can't be done via rapids-cpm, because the library has no cmake | ||
# build setup. But still it can be imported with CPM. | ||
# | ||
# This function is based on the CPM example: https://github.com/cpm-cmake/CPM.cmake/blob/master/examples/asio-standalone/CMakeLists.txt | ||
# | ||
# import_standalone_asio([TAG github-tag] VERSION [version-stirng]) | ||
# | ||
function(import_standalone_asio) | ||
set(options "") | ||
set(args TAG VERSION) | ||
set(multi_args "") | ||
cmake_parse_arguments(IMPORT_STANDALONE_ASIO "${options}" "${args}" "${multi_args}") | ||
|
||
CPMAddPackage("gh:chriskohlhoff/asio#${IMPORT_STANDALONE_ASIO_TAG}@${IMPORT_STANDALONE_ASIO_VERSION}") | ||
|
||
# ASIO doesn't use CMake, we have to configure it manually. Extra notes for using on Windows: | ||
# | ||
# 1) If _WIN32_WINNT is not set, ASIO assumes _WIN32_WINNT=0x0501, i.e. Windows XP target, which is | ||
# definitely not the platform which most users target. | ||
# | ||
# 2) WIN32_LEAN_AND_MEAN is defined to make Winsock2 work. | ||
if(asio_ADDED) | ||
add_library(asio INTERFACE) | ||
|
||
target_include_directories(asio SYSTEM INTERFACE ${asio_SOURCE_DIR}/asio/include) | ||
|
||
target_compile_definitions(asio INTERFACE ASIO_STANDALONE ASIO_NO_DEPRECATED) | ||
|
||
target_link_libraries(asio INTERFACE Threads::Threads) | ||
|
||
if(WIN32) | ||
# macro see @ https://stackoverflow.com/a/40217291/1746503 | ||
macro(get_win32_winnt version) | ||
if(CMAKE_SYSTEM_VERSION) | ||
set(ver ${CMAKE_SYSTEM_VERSION}) | ||
string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver}) | ||
string(REGEX MATCH "^([0-9]+)" verMajor ${ver}) | ||
# Check for Windows 10, b/c we'll need to convert to hex 'A'. | ||
if("${verMajor}" MATCHES "10") | ||
set(verMajor "A") | ||
string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver}) | ||
endif("${verMajor}" MATCHES "10") | ||
# Remove all remaining '.' characters. | ||
string(REPLACE "." "" ver ${ver}) | ||
# Prepend each digit with a zero. | ||
string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver}) | ||
set(${version} "0x${ver}") | ||
endif() | ||
endmacro() | ||
|
||
if(NOT DEFINED _WIN32_WINNT) | ||
get_win32_winnt(ver) | ||
set(_WIN32_WINNT ${ver}) | ||
endif() | ||
|
||
message(STATUS "Set _WIN32_WINNET=${_WIN32_WINNT}") | ||
|
||
target_compile_definitions(asio INTERFACE _WIN32_WINNT=${_WIN32_WINNT} WIN32_LEAN_AND_MEAN) | ||
endif() | ||
endif() | ||
endfunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright (c) 2023 Maikel Nadolski | ||
* Copyright (c) 2023 NVIDIA Corporation | ||
* | ||
* Licensed under the Apache License Version 2.0 with LLVM Exceptions | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* https://llvm.org/LICENSE.txt | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
#include "./common.hpp" | ||
#include <execpools/asio/asio_thread_pool.hpp> | ||
|
||
struct RunThread { | ||
void operator()( | ||
execpools::asio_thread_pool& pool, | ||
std::size_t total_scheds, | ||
std::size_t tid, | ||
std::barrier<>& barrier, | ||
#ifndef STDEXEC_NO_MONOTONIC_BUFFER_RESOURCE | ||
std::span<char> buffer, | ||
#endif | ||
std::atomic<bool>& stop, | ||
exec::numa_policy numa) { | ||
int numa_node = numa.thread_index_to_node(tid); | ||
numa.bind_to_node(numa_node); | ||
auto scheduler = pool.get_scheduler(); | ||
std::mutex mut; | ||
std::condition_variable cv; | ||
while (true) { | ||
barrier.arrive_and_wait(); | ||
if (stop.load()) { | ||
break; | ||
} | ||
#ifndef STDEXEC_NO_MONOTONIC_BUFFER_RESOURCE | ||
pmr::monotonic_buffer_resource resource{ | ||
buffer.data(), buffer.size(), pmr::null_memory_resource()}; | ||
pmr::polymorphic_allocator<char> alloc(&resource); | ||
auto [start, end] = exec::_pool_::even_share(total_scheds, tid, pool.available_parallelism()); | ||
std::size_t scheds = end - start; | ||
std::atomic<std::size_t> counter{scheds}; | ||
auto env = exec::make_env(stdexec::prop{stdexec::get_allocator, alloc}); | ||
while (scheds) { | ||
stdexec::start_detached( // | ||
stdexec::schedule(scheduler) // | ||
| stdexec::then([&] { | ||
auto prev = counter.fetch_sub(1); | ||
if (prev == 1) { | ||
std::lock_guard lock{mut}; | ||
cv.notify_one(); | ||
} | ||
}), | ||
env); | ||
--scheds; | ||
} | ||
#else | ||
auto [start, end] = exec::_pool_::even_share(total_scheds, tid, pool.available_parallelism()); | ||
std::size_t scheds = end - start; | ||
std::atomic<std::size_t> counter{scheds}; | ||
while (scheds) { | ||
stdexec::start_detached( // | ||
stdexec::schedule(scheduler) // | ||
| stdexec::then([&] { | ||
auto prev = counter.fetch_sub(1); | ||
if (prev == 1) { | ||
std::lock_guard lock{mut}; | ||
cv.notify_one(); | ||
} | ||
})); | ||
--scheds; | ||
} | ||
#endif | ||
std::unique_lock lock{mut}; | ||
cv.wait(lock, [&] { return counter.load() == 0; }); | ||
lock.unlock(); | ||
barrier.arrive_and_wait(); | ||
} | ||
} | ||
}; | ||
|
||
int main(int argc, char** argv) { | ||
my_main<execpools::asio_thread_pool, RunThread>(argc, argv); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.