通过示例点产品在Cuda中使用锁

詹姆士

我正在阅读杰森·桑德斯(Jason Sanders)和爱德华·坎德罗特(Edward Kandrot)的书“ Cuda by Example”,对使用锁来计算两个数组的点积有疑问(请参阅链接pdf的第254-258页)。他们定义了lock.h头文件:

#ifndef __LOCK_H__
#define __LOCK_H__


struct Lock{
    int *mutex;
    Lock(){
        int state = 0;
        cudaMalloc((void**)&mutex, sizeof(int));
        cudaMemcpy(mutex, &state, sizeof(int), cudaMemcpyHostToDevice);
    }

    ~Lock(){
        cudaFree(mutex);
    }

    __device__ void lock(){
        while (atomicCAS(mutex, 0 ,1) != 0);
    }

    __device__ void unlock(){
        atomicExch(mutex, 0);
    }
};


#endif

然后,他们将其点积内核称为:

int main()
{
    // bunch of code, initialization etc

    Lock lock;
    dot<<<blocksPerGrid,threadsPerBlock>>>(lock, dev_a, dev_b, dev_c);

    // more code, frees, etc
} 

点内核声明为:

__global__ void dot(Lock lock, float *a, float *b, float *c);

因为Lock结构不包含复制构造函数,这是否会创建无效的free?我们按值传递锁,该锁仅按值复制互斥体指针。当我们退出内核时,析构函数在此互斥指针上调用cudaFree。我认为当我们退出主函数时,析构函数将再次被调用,但是互斥体已经释放了!我问是因为在使用相同的想法时,在另一个较大的代码中出现cudeErrorInvalidDevicePointer错误,我认为问题是没有复制构造函数。

刺柏

是的,您是对的,将会拨打一个额外的dtor电话-您也可以自行检查...

这是一个简单的示例进行验证:

#include <iostream>
#include <cuda_runtime.h>

struct A {
    A()  { std::cout << "ctor for " << this << std::endl << std::flush; }
    ~A() { std::cout << "dtor for " << this << std::endl << std::flush; }
};

__global__ void foo(A device_a) { }

int main(void) {
    A host_a;
    foo<<<1,1>>>(host_a);
    cudaDeviceReset();
    return 0;
}

输出为:

ctor for 0x7ffe584c85bf
dtor for 0x7ffe584c85df
dtor for 0x7ffe584c85bf

因此,您将获得默认的副本ctor。并且两个副本的构建和销毁都在主机上进行(这些副本仅是主机功能,而设备没有<iostream>)。我实际上发现这有点奇怪,但是我想这是CUDA的“ C-ish”起源的一部分,它像POD一样对待内核参数。看到ctor和dtor如何具有__device____host__限定符,这尤其令人惊讶

但是,cudaFree()在该示例中对的额外调用应该没有问题(手指交叉):CUDA Runtime API手册的3.9节说,该调用应该失败并返回cudaErrorInvalidDevicePointer

尽管如此,那仍然是糟糕的编程实践,并且应该以不同的方式编写IMO的结构。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

通过示例在Cuda中使用非常简单的教程遇到的问题

来自分类Dev

CUDA C假人点产品

来自分类Dev

在tbb :: parallel_for中使用tbb :: queueing互斥锁的简单示例程序无法编译

来自分类Dev

在Go中使用互斥锁

来自分类Dev

在Java中使用同步锁

来自分类Dev

为什么ThreadSanitizer使用此无锁示例报告比赛?

来自分类Dev

如何在Julia中使用锁

来自分类Dev

在Java中使用文件锁复制文件

来自分类Dev

在C中使用互斥锁同步pthread

来自分类Dev

在DPC中使用唯一锁

来自分类Dev

在内核中使用读写锁死锁

来自分类Dev

在C中使用互斥锁同步pthread

来自分类Dev

.NET中使用密钥的互斥锁

来自分类Dev

如何在程序中使用乐观锁?

来自分类Dev

在libtorrent示例中使用maketorrent

来自分类Dev

通过一个简单的示例学习在Firebird中使用执行块

来自分类Dev

如何通过点积产品达到峰值CPU性能?

来自分类Dev

让客户在其顶级产品中使用特定产品

来自分类Dev

在Android Studio的产品风格中使用Crashlytics

来自分类Dev

在Laravel路线中使用产品搜索

来自分类Dev

在Django中使用Stripe API创建产品

来自分类Dev

在Tkinter中使用锚点

来自分类Dev

无法使用clang在Linux上构建cuda 7.0示例

来自分类Dev

如何在NSubstitute中使用AutoFixture的示例

来自分类Dev

在JavaScript中使用reduceRight的真实示例

来自分类Dev

为什么在此示例中使用q?

来自分类Dev

在此示例中使用“收益”的正确方法

来自分类Dev

为什么在此示例中使用.bind()?

来自分类Dev

在Amazon Lambda示例中使用异步?