对于在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".
这是代码.它基本上是使用原子操作计算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 …这是一个简单的计算着色器来说明我的问题
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);
        } …我想在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
}
我不相信我能用任何原子功能做到这一点.我需要锁定几个全局内存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;
}
内核应该在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): …我正在写一个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;
}
输出是:
In kernel count is 1
In kernel count is 1
In kernel count is 1
In kernel count is 1
count is 1
我不明白为什么它没有递增.谁能帮忙
gpu-atomics ×10
cuda ×9
atomic ×2
concurrency ×2
algorithm ×1
glsl ×1
matrix ×1
opengl ×1
ptxas ×1
reduction ×1