【CUDA学习日记】3.4 动态并行

之前,所有的核函数都是从主机线程中被调用。内核启动是静态的,意味着所有的并行任务必须在程序运行前就确定好。动态并行是指在一个CUDA内核执行时,该内核能够动态地启动其他内核的能力。启用动态并行,你需要在编译CUDA代码时使用-rdc=true选项,并且确保你的GPU支持这一特性。

在动态并行中,内核执行分为两种类型:父母和孩子。父线程、父线程块或父网格启

动一个新的网格,即子网格。子线程、子线程块或子网格被父母启动。子网格必须在父线程、父线程块或父网格完成之前完成。只有在所有的子网格都完成之后,父母才会完成。

3.4.1 GPU 上嵌套Hello world

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <windows.h>
#include "../common/common.h"

__global__ void nestedHelloWorld(int const iSize, int iDepth){
    int tid = threadIdx.x;
    printf("Recursion = %d : helloworld from thread %d block %d\n", iDepth, tid, blockIdx.x);

    if (iSize == 1) return;

    int nthreads = iSize >> 1;
    if (tid == 0 && nthreads){
        nestedHelloWorld<<<1, nthreads>>>(nthreads, ++iDepth);
        printf("------> nested execution depth : %d\n" , iDepth);
    }
}

int main(int argc, char **argv)
{
    int size = 8;
    int blocksize = 8;   // initial block size
    int igrid = 1;

    if(argc > 1)
    {
        igrid = atoi(argv[1]);
        size = igrid * blocksize;
    }

    dim3 block (blocksize, 1);
    dim3 grid  ((size + block.x - 1) / block.x, 1);
    printf("%s Execution Configuration: grid %d block %d\n", argv[0], grid.x,
           block.x);

    nestedHelloWorld<<<grid, block>>>(block.x, 0);

    CHECK(cudaDeviceReset());
    return 0;
}

编译: nvcc .\nestedHelloworld.cu -o .\nestedHelloworld -rdc=true

输出:

nestedHelloworld.exe Execution Configuration: grid 1 block 8

Recursion = 0 : helloworld from thread 0 block 0

Recursion = 0 : helloworld from thread 1 block 0

Recursion = 0 : helloworld from thread 2 block 0

Recursion = 0 : helloworld from thread 3 block 0

Recursion = 0 : helloworld from thread 4 block 0

Recursion = 0 : helloworld from thread 5 block 0

Recursion = 0 : helloworld from thread 6 block 0

Recursion = 0 : helloworld from thread 7 block 0

------> nested execution depth : 1

Recursion = 1 : helloworld from thread 0 block 0

Recursion = 1 : helloworld from thread 1 block 0

Recursion = 1 : helloworld from thread 2 block 0

Recursion = 1 : helloworld from thread 3 block 0

------> nested execution depth : 2

Recursion = 2 : helloworld from thread 0 block 0

Recursion = 2 : helloworld from thread 1 block 0

------> nested execution depth : 3

Recursion = 3 : helloworld from thread 0 block 0

由输出可以看出, 主机调用的父网格有1个线程块和8个线程。nestedHelloWorld

核函数递归地调用三次,每次调用的线程数是上一次的一半。

相关推荐
2303_Alpha11 小时前
SpringBoot
笔记·学习
萘柰奈11 小时前
Unity学习----【进阶】TextMeshPro学习(三)--进阶知识点(TMP基础设置,材质球相关,两个辅助工具类)
学习·unity
沐矢羽12 小时前
Tomcat PUT方法任意写文件漏洞学习
学习·tomcat
好奇龙猫12 小时前
日语学习-日语知识点小记-进阶-JLPT-N1阶段蓝宝书,共120语法(10):91-100语法+考え方13
学习
向阳花开_miemie12 小时前
Android音频学习(十八)——混音流程
学习·音视频
工大一只猿13 小时前
51单片机学习
嵌入式硬件·学习·51单片机
c0d1ng13 小时前
量子计算学习(第十四周周报)
学习·量子计算
Hello_Embed20 小时前
STM32HAL 快速入门(二十):UART 中断改进 —— 环形缓冲区解决数据丢失
笔记·stm32·单片机·学习·嵌入式软件
咸甜适中20 小时前
rust语言 (1.88) 学习笔记:客户端和服务器端同在一个项目中
笔记·学习·rust
Magnetic_h21 小时前
【iOS】设计模式复习
笔记·学习·ios·设计模式·objective-c·cocoa