对于在CUDA中使用原子操作,是否需要包含一些CUDA头文件?CUDA编程指南似乎对此非常紧张.
下面给出的代码glmax.cu给出了以下编译错误.
gaurish108 MyPractice: nvcc glmax.cu -o glmax
glmax.cu(11): error: identifier "atomicMax" is undefined
1 error detected in the compilation of "/tmp/tmpxft_000010fa_00000000-4_glmax.cpp1.ii".
Run Code Online (Sandbox Code Playgroud)
这是代码.它基本上是使用原子操作计算GPU上阵列的最大值atomicMax.由于我是CUDA的新手,因此我确信这是一个非常简单的代码,但我写这篇文章是为了帮助自己理解原子操作.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
__global__ void global_max(int* values, int* gl_max)
{
int i=threadIdx.x + blockDim.x * blockIdx.x;
int val=values[i];
atomicMax(gl_max,val);
}
int main(void)
{
int array_size=5;
int num_bytes=array_size*sizeof(int);
int *device_array=0;
int *host_array=0;
int *device_max=0;
int *host_max=0;
//Allocate memory on the host
host_array=(int*)malloc(num_bytes);
//Allocate memory on the device
cudaMalloc((void**)&device_array,num_bytes);
cudaMalloc((void**)&device_max,sizeof(int));
//If either memory allocation failed, report an …Run Code Online (Sandbox Code Playgroud) 这是一个简单的计算着色器来说明我的问题
layout(local_size_x = 64) in;
// Persistent LIFO structure with a count of elements
layout(std430, binding = 0) restrict buffer SMyBuffer
{
int count;
float data[];
} MyBuffer;
bool AddDataElement(uint i);
float ComputeDataElement(uint i);
void main()
{
for (uint i = gl_GlobalInvocationID.x; i < some_end_condition; i += gl_WorkGroupSize.x)
{
if (AddDataElement(i))
{
// We want to store this data piece in the next available free space
uint dataIndex = atomicAdd(MyBuffer.count, 1);
// [1] memoryBarrierBuffer() ?
MyBuffer.data[dataIndex] = ComputeDataElement(i);
} …Run Code Online (Sandbox Code Playgroud) 我想在CUDA中实现这个原子函数:
__device__ float lowest; // global var
__device__ int lowIdx; // global var
float realNum; // thread reg var
int index; // thread reg var
if(realNum < lowest) {
lowest= realNum; // the new lowest
lowIdx= index; // update the 'low' index
}
Run Code Online (Sandbox Code Playgroud)
我不相信我能用任何原子功能做到这一点.我需要锁定几个全局内存loc以获取一些指令.我可以用PTXAS(汇编)代码实现这个吗?
我的问题是如何在 CUDA 中进行原子加载。原子交换可以模拟原子存储。原子加载是否可以以类似的方式廉价地模拟?我可以使用带有 0 的原子添加来自动加载内容,但我认为它很昂贵,因为它执行原子读取-修改-写入而不是仅读取。
我正在研究 GPU 编程,并有一个关于在线程中修改全局数组的问题。
__device__ float data[10] = {0,0,0,0,0,0,0,0,0,1};
__global__ void gradually_set_global_data() {
while (1) {
if (data[threadIdx.x + 1]) {
atomicAdd(&data[threadIdx.x], data[threadIdx.x + 1]);
break;
}
}
}
int main() {
gradually_set_global_data<<<1, 9>>>();
cudaDeviceReset();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
内核应该在data预期保持 [1,1,1,1,1,1,1,1,1,1] 的情况下完成执行,但它陷入了无限循环。为什么会发生这种情况?
我试图在Visual Studio 2010下使用CUDA 4.2编译一些CUDA代码(我使用Parallel Nsight 2.2创建了这个CUDA项目),但我遇到了一个原子问题"错误:标识符"atomicAdd"未定义",我仍然不能检查几个论坛后解决.
所以我试图从CUDA SDK Samples获取一些信息.首先,我在CUDA SDK中运行了simpleAtomicIntrinsics示例,该示例通过了测试.然后,我将此示例中的所有文件复制到visual studio 2010中的新CUDA 4.2项目并编译它们,结果如下.
1> E:\CUDA exercise Codes\CUDA_EXERCISES\CUDA_EXERCISES\CUDA_EXERCISES>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\bin\nvcc.exe" -gencode=arch=compute_20,code=\"sm_20,compute_20\" -gencode=arch=compute_20,code=\"sm_20,compute_20\" -gencode=arch=compute_10,code=\"sm_10,compute_10\" --use-local-env --cl-version 2010 -ccbin "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.2\include" -G --keep-dir "Debug" -maxrregcount=0 --machine 32 --compile -g -Xcompiler "/EHsc /nologo /Od /Zi /MDd " -o "Debug\simpleAtomicIntrinsics.cu.obj" "E:\CUDA exercise Codes\CUDA_EXERCISES\CUDA_EXERCISES\CUDA_EXERCISES\simpleAtomicIntrinsics.cu"
1> simpleAtomicIntrinsics.cu
1> tmpxft_00007220_00000000-3_simpleAtomicIntrinsics.compute_20.cudafe1.gpu
1> tmpxft_00007220_00000000-7_simpleAtomicIntrinsics.compute_20.cudafe2.gpu
1> simpleAtomicIntrinsics.cu
1>e:\cuda exercise codes\cuda_exercises\cuda_exercises\cuda_exercises\simpleAtomicIntrinsics_kernel.cu(33): error : identifier "atomicAdd" is undefined
1>
1>e:\cuda exercise codes\cuda_exercises\cuda_exercises\cuda_exercises\simpleAtomicIntrinsics_kernel.cu(36): …Run Code Online (Sandbox Code Playgroud) 我正在写一个CUDA内核,它涉及计算给定矩阵的最大值,我正在评估可能性.我能找到的最好方法是:
强制每个线程在共享内存中存储一个值,然后使用减少算法来确定最大值(pro:最小差异缺点:共享内存在2.0设备上限制为48Kb)
我无法使用原子操作,因为它有读取和写入操作,因此线程无法通过同步线程同步.
还有其他想法进入你的脑海吗?
目前,我开发了一个基于GPU的程序,该程序使用多个内核,这些内核通过使用多个流同时启动.
在我的应用程序中,多个内核需要访问队列/堆栈,我计划使用原子操作.
但我不知道原子操作是否在多个内核同时启动之间起作用.请帮助我了解GPU上的原子操作的确切机制或有此问题经验的人.
我使用atomicInc()尝试过以下程序.
__global__ void ker(int *count)
{
int n=1;
int x = atomicInc ((unsigned int *)&count[0],n);
CUPRINTF("In kernel count is %d\n",count[0]);
}
int main()
{
int hitCount[1];
int *hitCount_d;
hitCount[0]=1;
cudaMalloc((void **)&hitCount_d,1*sizeof(int));
cudaMemcpy(&hitCount_d[0],&hitCount[0],1*sizeof(int),cudaMemcpyHostToDevice);
ker<<<1,4>>>(hitCount_d);
cudaMemcpy(&hitCount[0],&hitCount_d[0],1*sizeof(int),cudaMemcpyDeviceToHost);
printf("count is %d\n",hitCount[0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
In kernel count is 1
In kernel count is 1
In kernel count is 1
In kernel count is 1
count is 1
Run Code Online (Sandbox Code Playgroud)
我不明白为什么它没有递增.谁能帮忙
gpu-atomics ×10
cuda ×9
atomic ×2
concurrency ×2
algorithm ×1
glsl ×1
matrix ×1
opengl ×1
ptxas ×1
reduction ×1