cuda学习

CUDA 安装测试部分 https://blog.csdn.net/sunmc1204953974/article/details/51000970
CUDA的HelloWorld程序编写 https://www.cnblogs.com/neopenx/p/4643705.html
对多线程并行处理的解释:https://blog.csdn.net/sunmc1204953974/article/details/51025801
以下的CUDA知识全部转载自:https://blog.csdn.net/sunmc1204953974

数组中求立方和(CUDA编程举例)
//简单的CUDA程序,转载自:https://blog.csdn.net/sunmc1204953974/article/details/51025801
//代码功能:计算数组中数字的立方和
//maintest.cu文件
#include <stdio.h> 
#include <time.h>
#include <iostream>//CUDA RunTime API
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <atomic>using namespace std;
//数组的大小
#define DATA_SIZE 1048576
//程序中用到的线程数,注意要小于设备中的maxThreadsPerBlock变量
#define THREAD_NUM 1024
//GPU的运行频率
int gpu_clock_rate = 0;
int data[DATA_SIZE];void GenerateNumbers(int *number, int size)
{for (int i = 0; i < size; i++){number[i] = rand() % 10;}
}void PrintDeviceProp(const cudaDeviceProp &prop)
{printf("Device Name : %s.\n", prop.name);printf("totalGlobalMem : %d.\n", prop.totalGlobalMem);printf("sharedMemPerBlock : %d.\n", prop.sharedMemPerBlock);printf("regsPerBlock : %d.\n", prop.regsPerBlock);printf("warpSize : %d.\n", prop.warpSize);printf("memPitch : %d.\n", prop.memPitch);printf("maxThreadsPerBlock : %d.\n", prop.maxThreadsPerBlock);printf("maxThreadsDim[0 - 2] : %d %d %d.\n", prop.maxThreadsDim[0], prop.maxThreadsDim[1], prop.maxThreadsDim[2]);printf("maxGridSize[0 - 2] : %d %d %d.\n", prop.maxGridSize[0], prop.maxGridSize[1], prop.maxGridSize[2]);printf("totalConstMem : %d.\n", prop.totalConstMem);printf("major.minor : %d.%d.\n", prop.major, prop.minor);printf("clockRate : %d.\n", prop.clockRate);printf("textureAlignment : %d.\n", prop.textureAlignment);printf("deviceOverlap : %d.\n", prop.deviceOverlap);printf("multiProcessorCount : %d.\n", prop.multiProcessorCount);}//CUDA 初始化
bool InitCUDA()
{int count;//取得支持Cuda的装置的数目cudaGetDeviceCount(&count);//没有符合的硬件if (count == 0) {fprintf(stderr, "There is no device.\n");return false;}int i;for (i = 0; i < count; i++) {cudaDeviceProp prop;if (cudaGetDeviceProperties(&prop, i) == cudaSuccess) {gpu_clock_rate = prop.clockRate;cout << endl;PrintDeviceProp(prop);cout << "---" << endl;cout << endl;if (prop.major >= 1) {break;}}}if (i == count) {fprintf(stderr, "There is no device supporting CUDA 1.x.\n");return false;}cudaSetDevice(i);return true;
}__global__ static void SumOfSquares(int *num, int *result,clock_t *time)
{//表示目前的 thread 是第几个 thread(由 0 开始计算)const int tid = threadIdx.x;//计算每个线程需要完成的量const int size = DATA_SIZE / THREAD_NUM;int sum = 0;int i;//记录运算开始的时间clock_t start;//只在 thread 0(即 threadIdx.x = 0 的时候)进行记录if (tid == 0) start = clock();for (i = tid * size; i < (tid + 1) * size; i++) {sum += num[i] * num[i] * num[i];}result[tid] = sum;//计算时间的动作,只在 thread 0(即 threadIdx.x = 0 的时候)进行//相减得到的是GPU执行单元的频率,也就是GPU的时钟周期(timestamp),需要除以GPU的运行频率才能得到以秒为单位的时间if (tid == 0) *time = clock() - start;
}int maintest()
{srand(time(0));if (!InitCUDA()){return 0;}printf("CUDA initialized.\n");GenerateNumbers(data, DATA_SIZE);//显卡内存数据表示int *gpudata, *result;clock_t *time;cudaMalloc((void**)&gpudata, sizeof(int)*DATA_SIZE);cudaMalloc((void**)&result, sizeof(int)*THREAD_NUM);cudaMalloc((void**)&time, sizeof(clock_t));//cudaMemcpy将产生的随机数复制到显卡内存中//cudaMemcpy(gpudata, data, sizeof(int)*DATA_SIZE, cudaMemcpyHostToDevice);//在CUDA中执行函数,语法<<<block数目,thread数目,shared memory大小>>>(参数...);SumOfSquares << <1, THREAD_NUM, 0 >> >(gpudata, result, time);//从显卡数据复制到内存int sum[THREAD_NUM];clock_t time_use;cudaMemcpy(&sum,result,sizeof(int)*THREAD_NUM, cudaMemcpyDeviceToHost);cudaMemcpy(&time_use, time, sizeof(int), cudaMemcpyDeviceToHost);//freecudaFree(gpudata);cudaFree(result);cudaFree(time);long final_sum = 0;for (int i = 0; i < THREAD_NUM; i++){final_sum += sum[i];}cout << "gpu sum " << final_sum << endl;cout << "gpu time " << time_use << endl;cout << "gpu time(second) " << time_use*1.0/(gpu_clock_rate * 1000) << endl;long time_s, time_e;time_s = clock();final_sum = 0;for (int i = 0; i < DATA_SIZE; i++){final_sum += data[i] * data[i] * data[i];}time_e = clock();cout << "cpu sum " << final_sum << endl;cout << "cpu time(second) " << (time_e - time_s)*1.0/CLOCKS_PER_SEC<< endl;return 0;
}

cpu 文件代码

#include <stdio.h>
#include <iostream>
using namespace std;
//调用cu文件函数的接口
extern int maintest();
int main()
{maintest();return 0;
}

显示结果


Device Name : GeForce GT 630.
totalGlobalMem : -2147483648.
sharedMemPerBlock : 49152.
regsPerBlock : 65536.
warpSize : 32.
memPitch : 2147483647.
maxThreadsPerBlock : 1024.
maxThreadsDim[0 - 2] : 1024 1024 64.
maxGridSize[0 - 2] : 2147483647 65535 65535.
totalConstMem : 65536.
major.minor : 3.0.
clockRate : 875500.
textureAlignment : 512.
deviceOverlap : 1.
multiProcessorCount : 1.
---CUDA initialized.
gpu sum 212139366
gpu time 6795883
gpu time(second) 0.00776229
cpu sum 212139366
cpu time(second) 0.002
结果分析

倒数第一行和倒数第三行,可以看到gpu和cpu中的计算结果是一样的,sum=212139366,gpu中所花费时间为0.00776229秒。
可以看到CPU的运行时间比GPU还短,但如果把加和函数编写的复杂,就能明显的看到GPU并行计算的优势。

并行线程的解释

这段代码主要是对相互独立的单元进行计算时,可以编写CUDA函数进行调用,调用时内部的逻辑我个人的分析如下:多个线程会依据__global__函数的副本,几乎同一时间调用副本函数,进行并行的计算,多个线程之间独立运行;const int tid = threadIdx.x;这行代码会获得调用该副本函数的线程id,依据id可以执行具体的单元。

GPU显卡中显存连续存取
for (i = tid * size; i < (tid + 1) * size; i++) {sum += num[i] * num[i] * num[i];
}

这样for循环的编写没有利用到显存连续存取的优点,在GPU中,thread在等待数据读入时,会切换下一个thread,thread的切换速度要远比显存存取的速度要快,并行的处理如下图:
在这里插入图片描述
如果显存反复载入的话,太消耗时间,如果换一种for循环编程方式,速度会提高很多,

for (i = tid ; i < DATA_SIZE; i+= THREAD_NUM) {sum += num[i] * num[i] * num[i] ;	
}

显示结果如下:

CUDA initialized.
gpu sum 212259240
gpu time 1122455
gpu time(second) 0.00128207
cpu sum 212259240
cpu time(second) 0.002

可以看到GPU消耗时间是1122455个时钟周期,简单的改变比上一个结果的时间消耗6795883要快6倍。
GPU下的0.00128207秒的计算总耗时,终于比0.002秒的CPU耗时要短了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

英特尔第七任CEO敲定 斯旺为何受到董事会青睐?

来源&#xff1a;网易科技2019年1月最后一天&#xff0c;芯片巨头英特尔公司(Intel)宣布任命临时首席执行官罗伯特斯旺(Robert Swan)为正式CEO&#xff0c;从而结束了长达数月的猎头工作。此前&#xff0c;英特尔前任CEO布莱恩柯再奇(Brian Krzanich)因与员工存在“暧昧关系”而…

图灵奖得主长文报告:是什么开启了计算机架构的新黄金十年?

来源&#xff1a;AI科技评论摘要&#xff1a;2017 年图灵奖的两位得主 John L. Hennessy 和 David A. Patterson 就是这个新浪潮的见证者和引领者。近几年来&#xff0c;不论是普通消费者还是科研人员们都可以感受到两种浪潮&#xff0c;一种是CPU速度的提升越来越不显著了&…

ubuntu安装wine之后进不了系统

以前曾经装过一次wine&#xff0c;安装的时候没碰到什么问题&#xff0c;但卸载的时候却出问题了&#xff0c;把我nouvean显卡给删除了。 自然&#xff0c;我下一次启动的时候就进不了桌面了。所以我得重装一次&#xff0c;那一次重装的是整个系统&#xff01; 今天突然觉得evi…

5G到底有哪些能力

来源&#xff1a;工信头条作者&#xff1a;华为5G首席科学家 童文摘要&#xff1a;华为5G首席科学家告诉你5G到底有哪些能力&#xff01;2019年是5G产业进入全面商用的关键一年&#xff0c;全球5G网络的部署已经启动。2018年6月&#xff0c;5G独立组网标准冻结&#xff0c;5G完…

口琴简易吹奏法

摘自上海口琴说明书。 口琴体积小巧&#xff0c;携带方便&#xff0c;有"带着走的音乐"、"口袋里的钢琴"之称。 口琴是一种簧舌乐器&#xff0c;用嘴吹吸发音。 复音口琴每孔上下两个是同音&#xff0c;吹奏时两格内的簧片同时发音。 口琴的 "1、3…

商业航天:通往太空旅程的新门票

来源&#xff1a;资本实验室自1969年美国实现人类首次登月之后&#xff0c;很长一段时间里&#xff0c;人类对月球的探索计划因各种原因变得沉寂。近年来&#xff0c;随着各国航天科技的持续发展&#xff0c;人类正在启动对月球的全新探索旅程。今年1月3日&#xff0c;我国“嫦…

关于用css实现的文字超出部分显示省略号

文字超出部分显示省略号还是比较常用的一个效果,最近看到网上的一些方法亲自实践了一下,发现有些以前一些浏览器不能用的属性现在可以用了&#xff0c;于是研究了一番&#xff0c;现总结如下&#xff1a; 我们先来看下HTML代码&#xff1a; <div><p><span>用…

AIoT的生死局:未来的AIoT很赚钱,但目前的AI+IoT很花钱

来源&#xff1a;物联网智库整理摘要&#xff1a;AIoT目前仍处于发展的起步阶段&#xff0c;只能作为一种美好的愿想&#xff0c;无论从AI还是IoT本身来看&#xff0c;仍然存在着许许多多的问题。如同互联网等新兴技术发展初期一样&#xff0c;AIoT也多少存在追捧与泡沫。尽管从…

链表的经典问题

链表的经典问题 如何判断两个单链表是否相交&#xff0c;如果相交&#xff0c;找出交点&#xff08;两个链表都不存在环&#xff09; 如果两个单链表相交&#xff0c;那应该呈“Y”字形&#xff0c;也就是从交点以后的部分是两个链表的公共节点。 所以&#xff0c;判断是否相交…

亚马逊、谷歌和微软寸土必争的新战场

作者&#xff1a; Caroline Donnelly 编译&#xff1a;机器之能 张玺摘要&#xff1a;当亚马逊、谷歌与微软都表示要争取所有可能的垂直市场客户时&#xff0c;云服务三巨头在零售市场的竞争变得愈发有趣。云技术在零售市场应用方面表现抢眼&#xff0c;但是竞争问题正在影响客…

duilib环境配置以及简单入门介绍

内容全部为转载&#xff1a; VS2013的编译&#xff0c;https://www.cnblogs.com/Alberl/p/3342030.html duilib框架介绍&#xff0c;以及VS2013配置&#xff0c;创建工程&#xff0c;调试代码部分&#xff1a; https://blog.csdn.net/lanuage/article/details/52040306 https:/…

2019年汽车行业深度投资研究

来源&#xff1a;中泰证券2018年预计我国汽车销售负增长&#xff0c;为30年来首次&#xff0c;批发数据自5月份开始逐步下降&#xff0c;尤其是9月之后,销售增速加速下滑,判断汽车市场弱势的原因和持续时间长短&#xff0c;是思考2019年汽车行业投资策略的前提。我们认为&#…

有没有哪些数学猜想是验证到很大的数以后才发现是错的?

来源&#xff1a;孙天任算数学苑素数的分布密度为 ρ(x)~1/ln(x)&#xff0c;从而在 x 以内的素数个数——通常用 π(x) 表示——为&#xff1a; π(x) ~ Li(x) 其中 Li(x) ≡ ∫ 1/ln(x) dx 是对数积分函数 。这个结果有些读者可能也认出来了&#xff0c;它正是著名的素数定理…

徐铁:当深度学习握手脑科学-圣城会议归来

原创&#xff1a;许铁 来源&#xff1a;混沌巡洋舰耶路撒冷号称三教圣地&#xff0c; 而它的牛逼之处绝不仅在于宗教&#xff0c; 如果你深入了解&#xff0c; 你会发现它的科学&#xff0c;尤其是理论创新也同样牛逼&#xff0c; 尤其是在脑科学和人工智能方向。 当然神族…

重磅!联合国权威AI趋势报告,美中日韩四分天下

来源&#xff1a;智东西摘要&#xff1a;AI趋势报告&#xff0c;中美专利申请和科学出版数遥遥领先。近年来&#xff0c;随着AI从理论知识落地到全球市场&#xff0c;AI正以其潜在的革命性影响&#xff0c;持续推动技术和产业的重大变革&#xff0c;从天气预报、自动驾驶、癌症…

通信产业5G迭代,万亿机遇一触即发

来源&#xff1a;中银国际摘要&#xff1a;进入本世纪一零年代后&#xff0c;全球通信行业首先迎来了4G商用的元年。▌通信产业5G迭代促使中国企业突破进入本世纪一零年代后&#xff0c;全球通信行业首先迎来了4G商用的元年。LTE网络在世界各地开花&#xff0c;“管”领域的性能…

duilib中界面的布局方式

参考博客&#xff1a;https://blog.csdn.net/zhuhongshu/article/details/38531447 常用的布局默认为相对布局&#xff0c;默认floatfalse&#xff0c;该属性为true时&#xff0c;表示绝对布局&#xff1b; 相对布局方式可以依据界面自动调整控件大小。 最常用的VerticalLayout…

美丽新世界:这七个原因将让未来更美好

来源&#xff1a;资本实验室摘要&#xff1a;技术进步推动人类社会的进步。然而在现实生活中&#xff0c;对技术的恐惧困扰着相当一部分人。暴走的机器人、失控的AI、滥用的人体增强……这些经常出现于各种反乌托邦科幻故事中的场景也被认为是对技术破坏的一种警示。如果能够从…

学习OpenStack之 (4): Linux 磁盘、分区、挂载、逻辑卷管理 (Logical Volume Manager)

0. 背景&#xff1a; inux用户安装Linux操作系统时遇到的一个常见的难以决定的问题就是如何正确地评估各分区大小&#xff0c;以分配合适的硬盘空间。普通的磁盘分区管理方式在逻辑分区划分好之后就无法改变其大小&#xff0c;当一个逻辑分区存放不下某个文件时&#xff0c;这个…

写论文文献引用方式

打开百度学术&#xff1a; 如下&#xff1a;