【发布时间】:2019-08-22 14:31:03
【问题描述】:
我最近通过系统的包管理器在我的 arch-Linux 机器上安装了 Cuda,我一直在尝试通过运行一个简单的向量添加程序来测试它是否工作。
我只是将代码从this tutorial(都使用一个和多个内核)复制粘贴到一个名为cuda_test.cu 的文件中并运行
> nvcc cuda_test.cu -o cuda_test
在任何一种情况下,程序都可以运行,并且我没有收到任何错误(在程序中都没有崩溃,并且输出是没有错误)。但是当我尝试在程序上运行 Cuda 分析器时:
> sudo nvprof ./cuda_test
我得到结果:
==3201== NVPROF is profiling process 3201, command: ./cuda_test
Max error: 0
==3201== Profiling application: ./cuda_test
==3201== Profiling result:
No kernels were profiled.
No API activities were profiled.
==3201== Warning: Some profiling data are not recorded. Make sure cudaProfilerStop() or cuProfilerStop() is called before application exit to flush profile data.
后一个警告不是我的主要问题或问题的主题,我的问题是消息说没有对内核进行分析并且没有对 API 活动进行分析。
这是否意味着程序完全在我的 CPU 上运行?还是 nvprof 中的错误?
我找到了关于相同错误here 的讨论,但答案是安装了错误版本的 Cuda,在我的情况下,安装的版本是通过系统包管理器安装的最新版本(@ 987654323@)
有什么方法可以让 nvprof 显示预期的输出?
编辑
试图坚持最后的警告并不能解决问题:
添加对cudaProfilerStop()(或cuProfilerStop())的调用,并按照建议在末尾添加cudaDeviceReset();并链接适当的库(cuda_profiler_api.h或cudaProfiler.h)并编译
> nvcc cuda_test.cu -o cuda_test -lcuda
产生一个仍然可以运行的程序,但是当运行哪个 nvprof 时,它会返回:
==12558== NVPROF is profiling process 12558, command: ./cuda_test
Max error: 0
==12558== Profiling application: ./cuda_test
==12558== Profiling result:
No kernels were profiled.
No API activities were profiled.
==12558== Warning: Some profiling data are not recorded. Make sure cudaProfilerStop() or cuProfilerStop() is called before application exit to flush profile data.
======== Error: Application received signal 139
这并没有解决原来的问题,实际上又产生了新的错误;当cudaProfilerStop() 单独使用或与cuProfilerStop() 和cudaDeviceReset(); 一起使用时,也会发生同样的情况
代码
代码是从教程中复制的,用于测试 Cuda 是否正常工作,尽管我也包含了对 cudaProfilerStop() 和 cudaDeviceReset() 的调用;为清楚起见,此处包括:
#include <iostream>
#include <math.h>
#include <cuda_profiler_api.h>
// Kernel function to add the elements of two arrays
__global__
void add(int n, float *x, float *y)
{
int index = threadIdx.x;
int stride = blockDim.x;
for (int i = index; i < n; i += stride)
y[i] = x[i] + y[i];
}
int main(void)
{
int N = 1<<20;
float *x, *y;
cudaProfilerStart();
// Allocate Unified Memory – accessible from CPU or GPU
cudaMallocManaged(&x, N*sizeof(float));
cudaMallocManaged(&y, N*sizeof(float));
// initialize x and y arrays on the host
for (int i = 0; i < N; i++) {
x[i] = 1.0f;
y[i] = 2.0f;
}
// Run kernel on 1M elements on the GPU
add<<<1, 1>>>(N, x, y);
// Wait for GPU to finish before accessing on host
cudaDeviceSynchronize();
// Check for errors (all values should be 3.0f)
float maxError = 0.0f;
for (int i = 0; i < N; i++)
maxError = fmax(maxError, fabs(y[i]-3.0f));
std::cout << "Max error: " << maxError << std::endl;
// Free memory
cudaFree(x);
cudaFree(y);
cudaDeviceReset();
cudaProfilerStop();
return 0;
}
【问题讨论】:
-
最后一个警告是主要问题。您需要在应用程序退出之前使用 *ProfilerStop 调用或 cudaDeviceReset 刷新分析数据。这在文档中有明确讨论(假设您的 GPU 受 nvprof 支持,最新一代不支持,这也在发行说明中进行了描述)
-
@talonmies 不,这不起作用,请参阅编辑
-
建议不起作用的原因是调用分析器存在另一个问题——尽管添加建议行后的错误代码是找到问题的关键——见答案下面
标签: cuda