CUDA学习第二天: GPU核心与SM核心组件[通俗易懂]

1.CUDA的内存模型每个线程有自己的私有本地内存(localmemory),每个线快有包含共享内存,可以被线程块中所有线程共享,其声明周期与线程块一致。此外,所有的线程都可以访问全局内存(globalmemory)还可以访问一些只读内存块:常量内存(ConstantMemory)和纹理内存(TextureMemory).2.GPU的核心组件–SM(Streamin…

大家好,又见面了,我是你们的朋友全栈君。

1. CUDA的内存模型

每个线程有自己的私有本地内存(local memory) , 每个线快有包含共享内存, 可以被线程块中所有线程共享,其声明周期与线程块一致。

此外,所有的线程都可以访问全局内存(global memory) 还可以访问一些只读内存块: 常量内存(Constant Memory)和纹理内存(Texture Memory).

2. GPU的核心组件 – SM(Streaming Multiprocessor)

与CPU的多线程类似,一个Kernel实际上会启动很多线程,而多线程如果没有多核支持,在物理层也是无法实现并行的。

而GPU存在很多CUDA核心, 充分利用CUDA核心可以发挥GPU的并行计算能力。‘

SM的核心组件包括CUDA核心,共享内存,寄存器等,SM可以并发地执行数百个 线程,并发能力就取决与SM所拥有的资源数。

3.SIMI–(Single-Intruction, Multiple-Thread)单指令多线程

基本的执行单元是线程束(wraps),线程束包含32个线程,这些线程同时执行相同的指令,但是每个线程都包含自己的指令地址计数器和寄存器状态,也有自己独立的执行路径。

所以尽管线程束中的线程同时从同一程序地址执行,但是可能具有不同的行为,比如遇到了分支结构,一些线程可能进入这个分支,但是另外一些有可能不执行,它们只能死等,因为GPU规定线程束中所有线程在同一周期执行相同的指令,线程束分化会导致性能下降。

总之,就是网格和线程块只是逻辑划分一个kernel的所有线程其实在物理层是不一定同时并发的。所以kernel的grid和block的配置不同,性能会出现差异。另外,由于SM的基本执行单元是包含32个线程的线程束,所以block大小一般要设置为32的倍数。

4. 第一个CUDA示例,Cmake的配置等

#include <iostream>
#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_runtime_api.h>

void printDeviceProp(cudaDeviceProp& devProp, int dev)
{ 
   
	std::cout << "使用GPU device " << dev << ": " << devProp.name << std::endl;
    std::cout << "SM的数量:" << devProp.multiProcessorCount << std::endl;
    std::cout << "每个线程块的共享内存大小:" << devProp.sharedMemPerBlock / 1024.0 << " KB" << std::endl;
    std::cout << "每个线程块的最大线程数:" << devProp.maxThreadsPerBlock << std::endl;
    std::cout << "每个EM的最大线程数:" << devProp.maxThreadsPerMultiProcessor << std::endl;
    std::cout << "每个EM的最大线程束数:" << devProp.maxThreadsPerMultiProcessor / 32 << std::endl;
	
}


bool initCUDA(cudaDeviceProp& devProp)
{ 
   
	int count;
	cudaGetDeviceCount(&count);
	if(count == 0) { 
   return false;};
	
	
	int i;
	for(i=0; i<count; i++)
	{ 
   
		if(cudaGetDeviceProperties(&devProp, i) == cudaSuccess)
		{ 
   
			if(devProp.major >= 1)
			{ 
   
				printDeviceProp(devProp, i);
				break;
			}
		}
	}
	
	if(i == count) { 
   std::cout<<"CUDA can't support the device !"<<std::endl;	return false;};
	
	cudaSetDevice(i);
	
	return false;
}
int main()
{ 
   
    cudaDeviceProp devProp;
	
	if(initCUDA(devProp))
	{ 
   
		std::cout<<"CUDA initialized Succed. \n"<<std::endl;
	}
    //CHECK(cudaGetDeviceProperties(&devProp, dev));
    return 0;

}
  • CMakeLists.txt 的配置
cmake_minimum_required(VERSION 3.1)
project(CUDA_Toturials)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11")

#set the default path for built executables to the "bin" directory
set(CMAKE_BUILD_TYPE Debug)

set(EXECUTABLE_OUTPUT_PATH ${ 
   PROJECT_SOURCE_DIR}/bin)
SET( LIBRARY_OUTPUT_PATH ${ 
   PROJECT_SOURCE_DIR}/lib)
LINK_DIRECTORIES( ${ 
   PROJECT_SOURCE_DIR}/lib)
INCLUDE_DIRECTORIES( ${ 
   PROJECT_SOURCE_DIR}/include )

# openMp for parallel
# find_package(OpenMP)
# if(OPENMP_FOUND)
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
# endif()

find_package(CUDA 8.0 REQUIRED)
include_directories(${ 
   CUDA_INCLUDE_DIRS})

# 设置CUAD编译配置
set(CUDA_NVCC_FLAGS "-g -G")

# build option
set(GENCODE -gencode=arch=compute_35,code=sm_35)
set(GENCODE ${ 
   GENCODE} -gencode=arch=compute_30,code=sm_30)
set(GENCODE ${ 
   GENCODE} -gencode=arch=compute_20,code=sm_20)
set(GENCODE ${ 
   GENCODE} -gencode=arch=compute_10,code=sm_10)
set(GENCODE ${ 
   GENCODE} -gencode arch=compute_61,code=sm_61)

# 生成可执行文件
cuda_add_executable(main src/main.cpp)

# add_subdirectory(src)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/126025.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Antd的table筛选,表头columns的filters过滤清空

    Antd的table筛选,表头columns的filters过滤清空Form+Table实现了自定义筛选菜单的功能。具体可以参考https://ant.design/components/table-cn/#components-table-demo-custom-filter-panel。但是此功能会有bug:选择相应的搜索条件后,点击“搜索”按钮,Table会渲染相应的数据,且Table表头也有自带的过滤功能(实际上是column的filters属性起的作用);然后再点击“清除”按钮,所有的搜索条件和表头里filters过滤的条件都要被清除。但是Ta.

  • group by 与 where, having以及顺序

    group by 与 where, having以及顺序1.GROUPBY子句必须出现在WHERE子句之后,ORDERBY子句之前.HAVING语句必须在ORDERBY子句之后。(where先执行,再groupby分组;groupby先分组,having在执行。)2.除聚集计算语句外,SELECT语句中的每个列都必须在GROUPBY子句中给出。count()为聚集函数,vend_id在后面groupby中有,所以select后面有。sel…

  • 我裂开了,教给他如何搭建和使用代理服务器,他居然用来做这么不正经的事(爬虫,代理ip)[通俗易懂]

    我裂开了,教给他如何搭建和使用代理服务器,他居然用来做这么不正经的事(爬虫,代理ip)

  • 记一次遇到挖矿程序的经历「建议收藏」

    记一次遇到挖矿程序的经历「建议收藏」就在几天前,遇到了一次挖矿程序偷偷装在ECS阿里云服务器上的经历。那是一个风和日丽的上午,我和往常一样来到公司,倒杯水等待电脑打开,之后打开日常维护的几个系统。结果其中有一个OA系统,发现无法正常打开。一开始我以为是网络问题,但是发现打开其他网站正常,于是登上服务器准备探个究竟。登陆云服务器后,重启OA服务,发现报错,报错提示连接线程池连接不上。根据提示,怀疑是连不上部署在本地的数据服…

  • linux查看时间

    linux查看时间linux查看时间

  • Swing程序设计(简易文本编辑器数据结构课设)

    Java课程设计-基于Swing的文本编辑器1.介绍2.相关技术3.项目地址4.所需环境5.安装教程6.运行截图7.相关博客1.介绍设计一个类似于Windows记事本(Notepad)的Java程序。可以打开、新建、保存一个文本文件;对选中的文本进行各种编辑操作(设置字体、字号、字型、对齐方式、背景、前景色、复制、粘贴、剪切等);在文本中能够插入对象。2.相关技术Java的Swing编程Java的文件读写3.项目地址https://gitee.com/jack0240/text-edi

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号