为什么我没有 I/O-compute 与此代码重叠?
Why am I not getting I/O-compute overlap with this code?
以下程序:
#include <iostream>
#include <array>
using clock_value_t = long long;
__device__ void gpu_sleep(clock_value_t sleep_cycles)
{
clock_value_t start = clock64();
clock_value_t cycles_elapsed;
do { cycles_elapsed = clock64() - start; }
while (cycles_elapsed < sleep_cycles);
}
__global__ void dummy(clock_value_t duration_in_cycles)
{
gpu_sleep(duration_in_cycles);
}
int main()
{
const clock_value_t duration_in_clocks = 1e7;
const size_t buffer_size = 5e7;
constexpr const auto num_streams = 2;
std::array<char*, num_streams> host_ptrs;
std::array<char*, num_streams> device_ptrs;
std::array<cudaStream_t, num_streams> streams;
for (auto i=0; i<num_streams; i++) {
cudaMallocHost(&host_ptrs[i], buffer_size);
cudaMalloc(&device_ptrs[i], buffer_size);
cudaStreamCreateWithFlags(&streams[i], cudaStreamNonBlocking);
}
cudaDeviceSynchronize();
for (auto i=0; i<num_streams; i++) {
cudaMemcpyAsync(device_ptrs[i], host_ptrs[i], buffer_size,
cudaMemcpyDefault, streams[i]);
dummy<<<128, 128, 0, streams[i]>>>(duration_in_clocks);
cudaMemcpyAsync(host_ptrs[i], device_ptrs[i], buffer_size,
cudaMemcpyDefault, streams[i]);
}
for (auto i=0; i<num_streams; i++) { cudaStreamSynchronize(streams[i]); }
for (auto i=0; i<num_streams; i++) {
cudaFreeHost(host_ptrs[i]);
cudaFree(device_ptrs[i]);
}
}
应该导致第一个和第二个流上的工作重叠 I/O 和计算:当第一个流的主机到设备结束时,第一个流的内核可以启动,但第二个流的内核也可以启动主机到设备的传输。相反,我得到以下时间线,没有重叠:
我 认为 我已经涵盖了我的基础以确保重叠。流是非阻塞的(事实上,工作的排队在第一个 HtoD 完成之前就结束了);主机内存已固定...所以我看到重叠时缺少什么?
在具有 NVIDIA GTX 650 Ti Boost 的 GNU/Linux Mint 18.2 上使用 CUDA 8.0.61。但是驱动是v384.59.
好的,这一定是我的 GPU 型号的问题,因为使用 Fedora 25 和 GTX Titan X,我得到:
以下程序:
#include <iostream>
#include <array>
using clock_value_t = long long;
__device__ void gpu_sleep(clock_value_t sleep_cycles)
{
clock_value_t start = clock64();
clock_value_t cycles_elapsed;
do { cycles_elapsed = clock64() - start; }
while (cycles_elapsed < sleep_cycles);
}
__global__ void dummy(clock_value_t duration_in_cycles)
{
gpu_sleep(duration_in_cycles);
}
int main()
{
const clock_value_t duration_in_clocks = 1e7;
const size_t buffer_size = 5e7;
constexpr const auto num_streams = 2;
std::array<char*, num_streams> host_ptrs;
std::array<char*, num_streams> device_ptrs;
std::array<cudaStream_t, num_streams> streams;
for (auto i=0; i<num_streams; i++) {
cudaMallocHost(&host_ptrs[i], buffer_size);
cudaMalloc(&device_ptrs[i], buffer_size);
cudaStreamCreateWithFlags(&streams[i], cudaStreamNonBlocking);
}
cudaDeviceSynchronize();
for (auto i=0; i<num_streams; i++) {
cudaMemcpyAsync(device_ptrs[i], host_ptrs[i], buffer_size,
cudaMemcpyDefault, streams[i]);
dummy<<<128, 128, 0, streams[i]>>>(duration_in_clocks);
cudaMemcpyAsync(host_ptrs[i], device_ptrs[i], buffer_size,
cudaMemcpyDefault, streams[i]);
}
for (auto i=0; i<num_streams; i++) { cudaStreamSynchronize(streams[i]); }
for (auto i=0; i<num_streams; i++) {
cudaFreeHost(host_ptrs[i]);
cudaFree(device_ptrs[i]);
}
}
应该导致第一个和第二个流上的工作重叠 I/O 和计算:当第一个流的主机到设备结束时,第一个流的内核可以启动,但第二个流的内核也可以启动主机到设备的传输。相反,我得到以下时间线,没有重叠:
我 认为 我已经涵盖了我的基础以确保重叠。流是非阻塞的(事实上,工作的排队在第一个 HtoD 完成之前就结束了);主机内存已固定...所以我看到重叠时缺少什么?
在具有 NVIDIA GTX 650 Ti Boost 的 GNU/Linux Mint 18.2 上使用 CUDA 8.0.61。但是驱动是v384.59.
好的,这一定是我的 GPU 型号的问题,因为使用 Fedora 25 和 GTX Titan X,我得到: