- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下两个几乎相同的示例代码。 code1.cu 使用 cudaMalloc
和 cudaMemcpy
处理设备/主机变量值交换。
code2.cu使用cudaMallocManaged
,因此不需要cudaMemcpy
。当使用 cudaMallocManaged 时,我必须包含 cudaDeviceSynchronize()
才能获得正确的结果,而对于使用 cudaMalloc 的结果,则不需要这样做。我希望能得到一些关于为什么会发生这种情况的提示
code2.cu
#include <iostream>
#include <math.h>
#include <vector>
//
using namespace std;
// Kernel function to do nested loops
__global__
void add(int max_x, int max_y, float *tot, float *x, float *y)
{
int i = blockIdx.x*blockDim.x + threadIdx.x;
int j = blockIdx.y*blockDim.y + threadIdx.y;
if(i < max_x && j<max_y) {
atomicAdd(tot, x[i] + y[j]);
}
}
int main(void)
{
int Nx = 1<<15;
int Ny = 1<<15;
float *d_x = NULL, *d_y = NULL;
float *d_tot = NULL;
cudaMalloc((void **)&d_x, sizeof(float)*Nx);
cudaMalloc((void **)&d_y, sizeof(float)*Ny);
cudaMallocManaged((void **)&d_tot, sizeof(float));
// Allocate Unified Memory – accessible from CPU or GPU
vector<float> vx;
vector<float> vy;
// initialize x and y arrays on the host
for (int i = 0; i < Nx; i++)
vx.push_back(i);
for (int i = 0; i < Ny; i++)
vy.push_back(i*10);
//
float tot = 0;
for(int i = 0; i<vx.size(); i++)
for(int j = 0; j<vy.size(); j++)
tot += vx[i] + vy[j];
cout<<"CPU: tot: "<<tot<<endl;
//
cudaMemcpy(d_x, vx.data(), vx.size()*sizeof(float), cudaMemcpyHostToDevice);
cudaMemcpy(d_y, vy.data(), vy.size()*sizeof(float), cudaMemcpyHostToDevice);
//
int blockSize; // The launch configurator returned block size
int minGridSize; // The minimum grid size needed to achieve the
cudaOccupancyMaxPotentialBlockSize( &minGridSize, &blockSize, add, 0, Nx+Ny);
//.. bx*by can not go beyond the blockSize, or hardware limit, which is 1024;
//.. bx*bx = blockSize && bx/by=Nx/Ny, solve the equation
int bx = sqrt(blockSize*Nx/(float)Ny);
int by = bx*Ny/(float)Nx;
dim3 blockSize_3D(bx, by);
dim3 gridSize_3D((Nx+bx-1)/bx, (Ny+by+1)/by);
cout<<"blockSize: "<<blockSize<<endl;
cout<<"bx: "<<bx<<" by: "<<by<<" gx: "<<gridSize_3D.x<<" gy: "<<gridSize_3D.y<<endl;
// calculate theoretical occupancy
int maxActiveBlocks;
cudaOccupancyMaxActiveBlocksPerMultiprocessor( &maxActiveBlocks, add, blockSize, 0);
int device;
cudaDeviceProp props;
cudaGetDevice(&device);
cudaGetDeviceProperties(&props, device);
float occupancy = (maxActiveBlocks * blockSize / props.warpSize) /
(float)(props.maxThreadsPerMultiProcessor /
props.warpSize);
printf("Launched blocks of size %d. Theoretical occupancy: %f\n",
blockSize, occupancy);
// Run kernel on 1M elements on the GPU
tot = 0;
add<<<gridSize_3D, blockSize_3D>>>(Nx, Ny, d_tot, d_x, d_y);
// Wait for GPU to finish before accessing on host
//cudaDeviceSynchronize();
tot =*d_tot;
//
//
cout<<" GPU: tot: "<<tot<<endl;
// Free memory
cudaFree(d_x);
cudaFree(d_y);
cudaFree(d_tot);
return 0;
}
code1.cu
#include <iostream>
#include <math.h>
#include <vector>
//
using namespace std;
// Kernel function to do nested loops
__global__
void add(int max_x, int max_y, float *tot, float *x, float *y)
{
int i = blockIdx.x*blockDim.x + threadIdx.x;
int j = blockIdx.y*blockDim.y + threadIdx.y;
if(i < max_x && j<max_y) {
atomicAdd(tot, x[i] + y[j]);
}
}
int main(void)
{
int Nx = 1<<15;
int Ny = 1<<15;
float *d_x = NULL, *d_y = NULL;
float *d_tot = NULL;
cudaMalloc((void **)&d_x, sizeof(float)*Nx);
cudaMalloc((void **)&d_y, sizeof(float)*Ny);
cudaMalloc((void **)&d_tot, sizeof(float));
// Allocate Unified Memory – accessible from CPU or GPU
vector<float> vx;
vector<float> vy;
// initialize x and y arrays on the host
for (int i = 0; i < Nx; i++)
vx.push_back(i);
for (int i = 0; i < Ny; i++)
vy.push_back(i*10);
//
float tot = 0;
for(int i = 0; i<vx.size(); i++)
for(int j = 0; j<vy.size(); j++)
tot += vx[i] + vy[j];
cout<<"CPU: tot: "<<tot<<endl;
//
cudaMemcpy(d_x, vx.data(), vx.size()*sizeof(float), cudaMemcpyHostToDevice);
cudaMemcpy(d_y, vy.data(), vy.size()*sizeof(float), cudaMemcpyHostToDevice);
//
int blockSize; // The launch configurator returned block size
int minGridSize; // The minimum grid size needed to achieve the
cudaOccupancyMaxPotentialBlockSize( &minGridSize, &blockSize, add, 0, Nx+Ny);
//.. bx*by can not go beyond the blockSize, or hardware limit, which is 1024;
//.. bx*bx = blockSize && bx/by=Nx/Ny, solve the equation
int bx = sqrt(blockSize*Nx/(float)Ny);
int by = bx*Ny/(float)Nx;
dim3 blockSize_3D(bx, by);
dim3 gridSize_3D((Nx+bx-1)/bx, (Ny+by+1)/by);
cout<<"blockSize: "<<blockSize<<endl;
cout<<"bx: "<<bx<<" by: "<<by<<" gx: "<<gridSize_3D.x<<" gy: "<<gridSize_3D.y<<endl;
// calculate theoretical occupancy
int maxActiveBlocks;
cudaOccupancyMaxActiveBlocksPerMultiprocessor( &maxActiveBlocks, add, blockSize, 0);
int device;
cudaDeviceProp props;
cudaGetDevice(&device);
cudaGetDeviceProperties(&props, device);
float occupancy = (maxActiveBlocks * blockSize / props.warpSize) /
(float)(props.maxThreadsPerMultiProcessor /
props.warpSize);
printf("Launched blocks of size %d. Theoretical occupancy: %f\n",
blockSize, occupancy);
// Run kernel on 1M elements on the GPU
tot = 0;
add<<<gridSize_3D, blockSize_3D>>>(Nx, Ny, d_tot, d_x, d_y);
// Wait for GPU to finish before accessing on host
//cudaDeviceSynchronize();
//
cudaMemcpy(&tot, d_tot, sizeof(float), cudaMemcpyDeviceToHost);
//
cout<<" GPU: tot: "<<tot<<endl;
// Free memory
cudaFree(d_x);
cudaFree(d_y);
cudaFree(d_tot);
return 0;
}
//Code2.cu has the following output:
//
//CPU: tot: 8.79609e+12
//blockSize: 1024
//bx: 32 by: 32 gx: 1024 gy: 1025
//Launched blocks of size 1024. Theoretical occupancy: 1.000000
//GPU: tot: 0
删除cudaDeviceSynchronize()
上的注释后,
GPU: tot: 8.79609e+12
最佳答案
CUDA 内核启动是异步的。这意味着它们的执行独立于启动它们的 CPU 线程。
由于这种异步启动,当您的 CPU 线程代码开始测试结果时,不能保证 CUDA 内核已完成(甚至启动)。
因此需要等待GPU内核完成,cudaDeviceSynchronize()
正是这样做的。 cudaMemcpy
还具有同步效果,因此当您删除cudaMemcpy
时操作,您会失去同步,但是 cudaDeviceSynchronize()
恢复它。
关于cudaMallocManaged 和 cudaDeviceSynchronize(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58695262/
我有以下两个几乎相同的示例代码。 code1.cu 使用 cudaMalloc 和 cudaMemcpy 处理设备/主机变量值交换。 code2.cu使用cudaMallocManaged,因此不需要
在Nvidia开发人员博客中:An Even Easier Introduction to CUDA,作者解释: To compute on the GPU, I need to allocate m
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我有一个由主机设备生成的 Eigen 数组,我想通过 CUDA 的统一内存将其放入 GPU。我发现的大多数示例首先将指针传递给 cudaMallocManaged 并在那里分配内存,然后再启动数组。我
在 CUDA 6.0 中尝试托管内存时,调用 cudaMallocManaged() 时出现操作不受支持。 #include "cuda_runtime.h" #include #define CH
我正在尝试将 CUDA 托管内存与我通过构造函数创建的对象结合使用。 struct A { A(float x) : x(x) {} float x; } __global__ voi
我对 cudamallocmanaged 的疑问是,如果我 malloc N 个数字,在 GPU 完成对这些数字的操作(比方说扫描操作)后,我只需要数组中的最后一个数字,并且只访问主机中的这个数字
如果(在 C++ + CUDA 中)cudaMallocManaged() 用于在主机和 GPU 内存中分配一个共享数组,并且程序遇到(比如在主机代码中)exit(1),是否这会在 GPU 中永久留下
我最近一直在玩 CUDA,希望尝试一下统一内存模型。我尝试使用示例代码,奇怪的是,在启动内核时,似乎没有任何值在更新。从主机修改统一数据工作正常,但启动的内核根本不会修改统一数据。 我的显卡是 GTX
我有一个 C 代码,我想翻译该代码以使用 CUDA。 解释完整的问题会非常复杂和冗长,这就是我遇到问题的一部分。 现在的问题是:我需要创建四棵 AVL 树(要插入树中的数据是从文件中读取的(实际文件,
我下载了CUDA 6.0 RC,写了一个简单的程序来测试统一内存。但是当我运行到 cudaMallocManaged 函数时,我得到了一个 cudaErrorNotSupported 错误。我的GPU
我有一个书面代码,我试图修改它以使其使用 CUDA,但我遇到了很多麻烦,目前,我试图使我想成为内核函数的函数无效,但我得到了一些错误 这是我收到的错误列表: black_scholes.cu(54):
我正在通过 NVIDIA GeForce GT 650M GPU 为我创建的模拟实现多线程。为了确保一切正常,我创建了一些辅助代码来测试一切正常。有一次我需要更新一个变量 vector (它们都可以单
我有一个像这样使用 cudaMallocManaged 的 C++ 类: MyMatrix::MyMatrix(int new_rows, int new_cols, int padrr, int
我是一名优秀的程序员,十分优秀!