Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cuda atomicMax+;AtomicCAS(atomicExch)_Cuda_Atomic - Fatal编程技术网

Cuda atomicMax+;AtomicCAS(atomicExch)

Cuda atomicMax+;AtomicCAS(atomicExch),cuda,atomic,Cuda,Atomic,我想问你们,是否有更好的方法将两个原子组合起来 我的目标是在J参数值列表(非常类似于双向输入)下找到一组K方程(超过32个)的最高结果,并保存该值和J索引 if (atomicMax(&max_k[id], t_max) < t_max) atomicExch(&indexMax[id],t_pos); if(atomicMax(&max_k[id],t_max)C>A是可能的(线程B的值最高,线程C的值高于A)我不确定,但是atomicExch可以以比atomicMax

我想问你们,是否有更好的方法将两个原子组合起来

我的目标是在J参数值列表(非常类似于双向输入)下找到一组K方程(超过32个)的最高结果,并保存该值和J索引

if (atomicMax(&max_k[id], t_max) < t_max) atomicExch(&indexMax[id],t_pos);
if(atomicMax(&max_k[id],t_max)
最初我们使用了上述方法,但是,由于我们确实希望每个线程都有更高的值,因此在同一个扭曲中,线程B>C>A是可能的(线程B的值最高,线程C的值高于A)我不确定,但是atomicExch可以以比atomicMax更高的线程顺序执行(正确吗?),因此我们尝试了一个关键部分,但它导致了死锁。毕竟,下面的解决方案似乎奏效了

下面的代码中是否有更好的方法或存在任何问题

__device__ int atomicMaxCAS(int* addressMax, int valMax, int* addressCAS, int valCas) {
        int oldCas = *addressCAS, assumedCas;
        int oldMax = *addressMax, assumedMax;
        do {
            assumedCas = oldCas;
            assumedMax = oldMax;
            oldMax = atomicMax(addressMax, valMax);
            if (oldMax < valMax) oldCas = atomicCAS(addressCAS, assumedCas, valCas);
        } while (assumedCas != oldCas || assumedMax != oldMax);
        return (oldMax);
    }
\uuuuu设备\uuuuuu原子最大值(int*addressMax,int-valMax,int*addressCAS,int-valCas){
int oldCas=*地址cas,假定为;
int oldMax=*地址最大值,假设最大值;
做{
假设值=旧值;
假设最大值=最大值;
oldMax=atomicMax(addressMax,valMax);
如果(oldMax
提前谢谢!我之所以能够开始写CUDA,是因为这些帖子都是关于

以下代码中是否存在任何问题

__device__ int atomicMaxCAS(int* addressMax, int valMax, int* addressCAS, int valCas) {
        int oldCas = *addressCAS, assumedCas;
        int oldMax = *addressMax, assumedMax;
        do {
            assumedCas = oldCas;
            assumedMax = oldMax;
            oldMax = atomicMax(addressMax, valMax);
            if (oldMax < valMax) oldCas = atomicCAS(addressCAS, assumedCas, valCas);
        } while (assumedCas != oldCas || assumedMax != oldMax);
        return (oldMax);
    }
是的,你不能像那样使用两个原子来期望一致的结果。您已经设置了可能的比赛条件

假设线程A执行
atomicMax
,并将旧值替换为100。然后线程B执行
atomicMax
,并将100值替换为110。然后假设线程B执行了
atomicCAS
,并替换了它的索引。然后线程A执行
atomicCAS
,并用线程A索引替换线程B索引。现在,最大值为110,索引对应于线程a

即使在单个扭曲中,也没有规定的原子操作执行顺序

有更好的办法吗


  • 因为您的值都是32位的量,所以您可能会对使用自定义的64位原子操作感兴趣,比如同时原子地更新值和索引

  • 对于大规模使用(大量线程),您可能需要探索一种新的方法。CUDA标签上有一些问题,例如和,讨论如何进行索引+值缩减

  • 开普勒上的全局原子学速度非常快,因此根据您的精确代码和缩减“密度”,全局原子缩减在性能方面可能不是一个大问题

    以下代码中是否存在任何问题

    __device__ int atomicMaxCAS(int* addressMax, int valMax, int* addressCAS, int valCas) {
            int oldCas = *addressCAS, assumedCas;
            int oldMax = *addressMax, assumedMax;
            do {
                assumedCas = oldCas;
                assumedMax = oldMax;
                oldMax = atomicMax(addressMax, valMax);
                if (oldMax < valMax) oldCas = atomicCAS(addressCAS, assumedCas, valCas);
            } while (assumedCas != oldCas || assumedMax != oldMax);
            return (oldMax);
        }
    
    是的,你不能像那样使用两个原子来期望一致的结果。您已经设置了可能的比赛条件

    假设线程A执行
    atomicMax
    ,并将旧值替换为100。然后线程B执行
    atomicMax
    ,并将100值替换为110。然后假设线程B执行了
    atomicCAS
    ,并替换了它的索引。然后线程A执行
    atomicCAS
    ,并用线程A索引替换线程B索引。现在,最大值为110,索引对应于线程a

    即使在单个扭曲中,也没有规定的原子操作执行顺序

    有更好的办法吗


  • 因为您的值都是32位的量,所以您可能会对使用自定义的64位原子操作感兴趣,比如同时原子地更新值和索引

  • 对于大规模使用(大量线程),您可能需要探索一种新的方法。CUDA标签上有一些问题,例如和,讨论如何进行索引+值缩减


  • 开普勒上的全局原子学速度非常快,因此根据您的精确代码和缩减“密度”,全局原子缩减在性能方面可能不是一个大问题

    你不能像那样使用两个原子并期望得到一致的结果。您已经设置了可能的比赛条件。假设线程A执行
    atomicMax
    ,并将旧值替换为100。然后线程B执行
    atomicMax
    ,并将100值替换为110。然后假设线程B执行了
    atomicCAS
    ,并替换了它的索引。然后线程A执行
    atomicCAS
    ,并用线程A索引替换线程B索引。现在,最大值为110,索引对应于线程a。即使在单个扭曲中,也没有规定原子操作的执行顺序。由于您的值都是32位量,您可能有兴趣使用自定义64位原子操作同时更新值和索引,原子操作。在这些正确性问题之上,减少速度可能更快,因为原子操作完全序列化了所有线程。@RobertCrovella:非常感谢!我相信它会解决的!你不能像那样使用两个原子并期望得到一致的结果。您已经设置了可能的比赛条件。假设线程A执行
    atomicMax
    ,并将旧值替换为100。然后线程B执行
    atomicMax
    ,并将100值替换为110。然后假设线程B执行了
    atomicCAS
    ,并替换了它的索引。然后线程A执行
    atomicCAS
    ,并用线程A索引替换线程B索引。现在,最大值为110,索引对应于线程a。即使在单个扭曲中,也没有规定原子操作的执行顺序。由于您的值都是32位量,您可能有兴趣使用自定义64位原子操作同时更新值和索引,原子性。在这些正确性问题之上,减少可能更快,因为原子操作是完全独立的