cuda编程002—流

news/2024/7/4 7:41:24

没有使用同步的情况:

#include <stdio.h>
#include <cuda_runtime.h>

__global__ void test_kernel(){

    printf("Message from Device.\n");
}
void test(){
    test_kernel<<<1, 1>>>();
}
#include <cuda_runtime.h>
#include <stdio.h>


void test();
int main(){
    
    test();
    printf("Message from Host.\n");

    getchar();

    return 0;
}

先调用的核函数,结果是先输出的Host:

 进行同步,代码如下:

#include <cuda_runtime.h>
#include <stdio.h>


void test();
int main(){
    
    test();
    // cudaDeviceSynchronize();  // 设备同步,整个GPU设备的同步等待任务完成
    cudaStreamSynchronize(nullptr);  // 流同步
    printf("Message from Host.\n");

    getchar();

    return 0;
}

输出结果:

cuda流整体笔记和代码

#include <math.h>
#include <stdio.h>
#include <cuda_runtime.h>

// 核函数
__global__ void test_kernel(float* array, int edge){

    int position = blockDim.x * blockIdx.x + threadIdx.x;
    if(position >= edge) return;

    array[position] *= 0.5f;
}

void test(cudaStream_t stream, float* array, int num){

    int threads = 512;
    int blocks = ceil(num / (float)threads);
    test_kernel<<<blocks, threads, 0, stream>>>(array, num);
}
#include <cuda_runtime.h>
#include <stdio.h>

// C++ 文件
void test(cudaStream_t stream, float* array, int num);

int main(){
    
    cudaStream_t stream;
    cudaEvent_t start, stop;

    // cudaEvent 是事件, 通常可以用来观察队列的执行情况
    // 比如,统计执行时间等操作
    cudaEventCreate(&start);
    cudaEventCreate(&stop);

    // 是重操作,不要随便创建太多,会消耗资源的
    // GPU计算的基本原则,是尽可能的使得计算密集,如果使用同步的话就是算一坨,等一会儿,算一坨,等一会。费劲吧啦的
    // 通过stream使得计算连续化、密集化,这样最好
    // GPU有个使用率,跟CPU使用了一样的,以GPU使用率越高越好
    cudaStreamCreate(&stream);

    cudaEventRecord(start, stream);

    int num = 10000;
    float* a = new float[num];
    for(int i=0; i < num; ++i)
        a[i] = i;

    float* a_device = nullptr;
    size_t a_bytes = sizeof(float) * num;
    cudaMalloc(&a_device, a_bytes);

    // 异步依赖的指针数据,必须在执行完成前一直存在,否则会造成例外结果
    // 并且异步执行时,对指针数据的修改,也需要合理的理解
    cudaMemcpyAsync(a_device, a, a_bytes, cudaMemcpyHostToDevice, stream);

    // 如果异步复制加上下面这段代码。会导致GPU边复制,CPU边修改,结果是a_device的内容不可控
    // 因此不要这么做,或者合理的去做你想做的
    // for(int i=0; i < num; ++i)
    //      a[i] = 500-i;


    test(stream, a_device, num);
    cudaMemcpyAsync(a, a_device, a_bytes, cudaMemcpyDeviceToHost, stream);

    cudaEventRecord(stop, stream);
    cudaEventSynchronize(stop);

    float ms = 0;
    cudaEventElapsedTime(&ms, start, stop);
    printf("核的执行时间是:%.8f ms\n", ms);

    // 打印前10个结果
    for(int i = 0; i < 10; ++i){
        printf(i == 0 ? "%.2f" : ", %.2f", a[i]);
    }
    printf("\n");
    
    // cudaStreamSynchronize(stream);
    // cudaDeviceSynchronize();  // 设备同步,整个GPU设备的同步等待任务完成
    // cudaStreamSynchronize(nullptr);  // 流同步

    /* 流的概率,stream, 类型全称是cudaStream_t
    1. 认为流是一个线程,任务级别的线程
    2. 认为流是一个任务队列
    3. 把异步执行的任务管理起来,在需要的时候等待或者做更多处理
    4. 默认流,指nullptr,如果给定为nullptr,就会使用默认流

    cuda核的执行都是异步的, 通过流来实现需要的同步

    任务队列
    队列特性:先进先出,后进后出

    cudaMemcpy 属于同步版本的内存拷贝
        等价于干了  ->  发送指令(任务队列中增加一个任务),我要复制了, cudaMemcpyAsync
                  ->  等待复制完成,cudaDeviceSynchronize

    */
    printf("Message from Host.\n");

    // 符合栈的方式分配和释放,就不用担心有bug
    delete [] a;
    
    cudaFree(a_device);
    cudaStreamDestroy(stream);
    cudaEventDestroy(start);
    cudaEventDestroy(stop);

    // getchar();

    return 0;
}

 


http://lihuaxi.xjx100.cn/news/1476710.html

相关文章

卓码软件测评简析:软件压力测试工具和流程有哪些?

在软件开发过程中&#xff0c;压力测试是非常重要的一项工作&#xff0c;它可以帮助客户评估软件系统在正常或异常负载下的性能表现。在这个领域&#xff0c;有很多不同的工具可供选择&#xff0c;每个工具具有其独特的特点和优势。那么常见的压力测试工具有哪些以及进行压力测…

1782. 统计点对的数目

给你一个无向图&#xff0c;无向图由整数 n &#xff0c;表示图中节点的数目&#xff0c;和 edges 组成&#xff0c;其中 edges[i] [ui, vi] 表示 ui 和 vi 之间有一条无向边。同时给你一个代表查询的整数数组 queries 。 第 j 个查询的答案是满足如下条件的点对 (a, b) 的数…

csdn冷知识:如何在csdn里输入公式或矩阵

目录 1 输入公式 2 输入矩阵 3 如何输入复杂公式 4 如何修改&#xff0c;已经生成的公式 1 输入公式 进入编辑模式点击右边的菜单&#xff1a;公式然后进入公式编辑器&#xff0c;选择右边的 ... 可以选择大括号等&#xff0c;右边还有矩阵符号选择后你需要创建几行几列的…

排水管网水位监测方案助力城市“排忧解涝”

城市排水管网是城市地下生命线之一&#xff0c;事关城市安全、健康运行和高质量发展。然而由于排水管网内部自身的复杂性、多样性、隐蔽性等因素的存在&#xff0c;致使城市排水管网存在雨污混接、管网淤堵、入渗入流、运行负荷等现象&#xff0c;导致城市出现内涝、溢流污染等…

2023年Java毕业设计题目推荐,怎样选题?500道毕业设计题目推荐

大家好&#xff0c;我是程序员徐师兄&#xff0c;最近有很多同学咨询&#xff0c;说毕业设计了&#xff0c;不知道选怎么题目好&#xff0c;有哪些是想需要注意的。 今天&#xff0c;我整理了一些Java毕业设计的题目,可以参考一下&#xff0c;希望对大家有所帮助 文章目录 一、…

22 从0到1:API测试怎么做?常用API测试工具简介

API 测试的基本步骤 准备测试数据&#xff08;可选&#xff0c;不一定所有 API 测试都需要这一步&#xff09;&#xff1b;通过 API 测试工具&#xff0c;发起对被测 API 的 request&#xff1b;验证返回结果的 response。 Postman操作步骤 发起 API 调用&#xff1b;添加结…

js判断类型:typeof Object.prototype.toString instanceof constructor有什么区别?一文讲清楚

相信很多小伙伴在使用js的过程中&#xff0c;经常会需要对js的数据类型进行判断&#xff0c;而js中可以对数据类型进行判断的方法有很多种&#xff0c;最常见的有typeof、Object.prototype.toString、instanceof、constructor这四种&#xff0c;那么他们有什么区别呢&#xff1…

u-view 的u-calendar 组件设置默认日期后,多次点击后,就不滚动到默认日期的位置

场景&#xff1a;uniapp开发微信小程序 vue2 uview版本&#xff1a;2.0.36 &#xff1b; u-calendar 组件设置默认日期后 我打开弹窗&#xff0c;再关闭弹窗&#xff0c; 重复两次 就不显示默认日期了 在源码中找到这个位置进行打印值&#xff0c;根据出bug前后的值进行…