【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

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

相关推荐
HyperAI超神经2 分钟前
【Triton 教程】triton_language.load
人工智能·学习·大语言模型·cpu·gpu·编程语言·triton
知识分享小能手17 分钟前
Ubuntu入门学习教程,从入门到精通,Linux操作系统概述(1)
linux·学习·ubuntu
yuhaiqun19891 小时前
Typora 技能进阶:从会写 Markdown 到玩转配置 + 插件高效学习笔记
经验分享·笔记·python·学习·学习方法·ai编程·markdown
我命由我123452 小时前
Python Flask 开发问题:ImportError: cannot import name ‘Markup‘ from ‘flask‘
开发语言·后端·python·学习·flask·学习方法·python3.11
全栈陈序员2 小时前
【Python】基础语法入门(二十)——项目实战:从零构建命令行 To-Do List 应用
开发语言·人工智能·python·学习
AA陈超2 小时前
枚举类 `ETriggerEvent`
开发语言·c++·笔记·学习·ue5
小六*^____^*3 小时前
虚拟列表学习
前端·javascript·学习
代码游侠3 小时前
学习笔记——IPC(进程间通信)
linux·运维·网络·笔记·学习·算法
charlie1145141913 小时前
如何把 Win32 窗口“置顶”(Windows + C++)
开发语言·c++·windows·笔记·学习·软件工程
名字不相符3 小时前
BUUCTF题目列表Misc题目(个人记录与学习)(第二页)
学习·misc·buuctf·萌新