I am trying to understand a performance issue that I can consistently reproduce on one of our servers.
My application creates one CPU thread per GPU. Each thread controls a dedicated GPU, and there is no interaction or synchronization between different GPUs. Each thread repeatedly performs the following sequence:
- Launch a small CUDA kernel (execution time is approximately 12 ms).
- Synchronize the stream.
- Launch the next kernel immediately.
When running on up to four GPUs concurrently, everything works as expected. However, once five or more GPUs are active simultaneously, I start seeing periodic stalls.
For example, when all eight GPUs are running, they execute several kernels continuously and then all GPUs stop launching new kernels at nearly the same time. After approximately 40–50 ms, kernel launches resume simultaneously on all GPUs.
From Nsight Systems, I can see that once the stall ends, the newly launched kernels reach the GPU with only a few microseconds of launch latency. In other words, the delay occurs before the kernels are submitted to the GPU, rather than after submission.
Interestingly, if I increase the execution time of each kernel by tens of times (thereby significantly reducing the kernel launch frequency from the CPU), the problem disappears completely.
This makes me suspect that the bottleneck may be related to the host-side submission path rather than GPU execution itself. One possibility I am considering is that there is some driver-side or system-side throttling or scheduling mechanism that limits the rate at which kernels (or other CUDA work) can be submitted across multiple GPUs. However, I have not found any documentation describing such a mechanism.
Could anyone suggest what components I should investigate next? For example:
- Is there any known driver-side throttling or fairness mechanism for high-frequency kernel launches across multiple GPUs?
- Are there any Nsight Systems, CUPTI, or Linux tracing tools that can help determine where the CPU is blocked before the kernels are submitted?
- Has anyone encountered similar behavior with many CPU threads driving multiple GPUs concurrently?
Any suggestions on how to narrow down the root cause would be greatly appreciated.
The application is running inside a Docker container provided by a cloud service provider. I do not have root access to the host OS, so my investigation is limited to the container environment.
docker OS:Ubuntu 22.04.4 LTS
Cuda in container(used to compile): Build cuda_13.0.r13.0/compiler.36260728_0
8 Graphic card: 4090
Output of nvidia-smi topo -m:
GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 CPU Affinity NUMA Affinity GPU NUMA ID
GPU0 X NODE NODE NODE SYS SYS SYS SYS 0-31,64-95 0 N/A
GPU1 NODE X NODE NODE SYS SYS SYS SYS 0-31,64-95 0 N/A
GPU2 NODE NODE X NODE SYS SYS SYS SYS 0-31,64-95 0 N/A
GPU3 NODE NODE NODE X SYS SYS SYS SYS 0-31,64-95 0 N/A
GPU4 SYS SYS SYS SYS X NODE NODE NODE 32-63,96-127 1 N/A
GPU5 SYS SYS SYS SYS NODE X NODE NODE 32-63,96-127 1 N/A
GPU6 SYS. SYS SYS SYS NODE NODE X NODE 32-63,96-127 1 N/A
GPU7 SYS. SYS SYS SYS NODE NODE NODE X 32-63,96-127 1 N/A
Snapshot of nsys:
