aboutsummaryrefslogtreecommitdiff
path: root/libc/startup
diff options
context:
space:
mode:
authorJoseph Huber <jhuber6@vols.utk.edu>2023-05-01 12:10:04 -0500
committerJoseph Huber <jhuber6@vols.utk.edu>2023-05-05 10:12:19 -0500
commitaea866c12cb428eb5fe062ffa910a63daff62b01 (patch)
tree9bf301a8c3c7f66949f2a36399ba2a5580b7b195 /libc/startup
parenta1be6f0290effb26ff5e0d7a43ab20931f1353a2 (diff)
downloadllvm-aea866c12cb428eb5fe062ffa910a63daff62b01.zip
llvm-aea866c12cb428eb5fe062ffa910a63daff62b01.tar.gz
llvm-aea866c12cb428eb5fe062ffa910a63daff62b01.tar.bz2
[libc] Support concurrent RPC port access on the GPU
Previously we used a single port to implement the RPC. This was sufficient for single threaded tests but can potentially cause deadlocks when using multiple threads. The reason for this is that GPUs make no forward progress guarantees. Therefore one group of threads waiting on another group of threads can spin forever because there is no guarantee that the other threads will continue executing. The typical workaround for this is to allocate enough memory that a sufficiently large number of work groups can make progress. As long as this number is somewhat close to the amount of total concurrency we can obtain reliable execution around a shared resource. This patch enables using multiple ports by widening the arrays to a predetermined size and indexes into them. Empty ports are currently obtained via a trivial linker scan. This should be imporoved in the future for performance reasons. Portions of D148191 were applied to achieve parallel support. Depends on D149581 Reviewed By: JonChesterfield Differential Revision: https://reviews.llvm.org/D149598
Diffstat (limited to 'libc/startup')
-rw-r--r--libc/startup/gpu/amdgpu/start.cpp5
-rw-r--r--libc/startup/gpu/nvptx/start.cpp5
2 files changed, 6 insertions, 4 deletions
diff --git a/libc/startup/gpu/amdgpu/start.cpp b/libc/startup/gpu/amdgpu/start.cpp
index d1dfc7b..84adb3b 100644
--- a/libc/startup/gpu/amdgpu/start.cpp
+++ b/libc/startup/gpu/amdgpu/start.cpp
@@ -15,7 +15,7 @@ extern "C" int main(int argc, char **argv, char **envp);
namespace __llvm_libc {
-static cpp::Atomic<uint32_t> lock = 0;
+static cpp::Atomic<uint32_t> lock[rpc::default_port_count] = {0};
extern "C" uintptr_t __init_array_start[];
extern "C" uintptr_t __init_array_end[];
@@ -43,7 +43,8 @@ extern "C" [[gnu::visibility("protected"), clang::amdgpu_kernel]] void
_begin(int argc, char **argv, char **env, void *in, void *out, void *buffer) {
// We need to set up the RPC client first in case any of the constructors
// require it.
- __llvm_libc::rpc::client.reset(__llvm_libc::gpu::get_lane_size(),
+ __llvm_libc::rpc::client.reset(__llvm_libc::rpc::default_port_count,
+ __llvm_libc::gpu::get_lane_size(),
&__llvm_libc::lock, in, out, buffer);
// We want the fini array callbacks to be run after other atexit
diff --git a/libc/startup/gpu/nvptx/start.cpp b/libc/startup/gpu/nvptx/start.cpp
index 83453ae..1d366dc 100644
--- a/libc/startup/gpu/nvptx/start.cpp
+++ b/libc/startup/gpu/nvptx/start.cpp
@@ -15,7 +15,7 @@ extern "C" int main(int argc, char **argv, char **envp);
namespace __llvm_libc {
-static cpp::Atomic<uint32_t> lock = 0;
+static cpp::Atomic<uint32_t> lock[rpc::default_port_count] = {0};
extern "C" {
// Nvidia's 'nvlink' linker does not provide these symbols. We instead need
@@ -47,7 +47,8 @@ extern "C" [[gnu::visibility("protected"), clang::nvptx_kernel]] void
_begin(int argc, char **argv, char **env, void *in, void *out, void *buffer) {
// We need to set up the RPC client first in case any of the constructors
// require it.
- __llvm_libc::rpc::client.reset(__llvm_libc::gpu::get_lane_size(),
+ __llvm_libc::rpc::client.reset(__llvm_libc::rpc::default_port_count,
+ __llvm_libc::gpu::get_lane_size(),
&__llvm_libc::lock, in, out, buffer);
// We want the fini array callbacks to be run after other atexit