常见计算机硬件设备硬件包含哪些内容常用输入输出设备

Mark wiens

发布时间:2023-06-10

  本文不是 CUDA 或 Numba 的综合指南,本文的目的是经由过程用Numba和CUDA编写一些简朴的示例,如许可让你理解更多GPU相干的常识,不管是是否是利用Python,以至C编写代码,它都是一个很好的入门资本……

常见计算机硬件设备硬件包含哪些内容常用输入输出设备

  本文不是 CUDA 或 Numba 的综合指南,本文的目的是经由过程用Numba和CUDA编写一些简朴的示例,如许可让你理解更多GPU相干的常识,不管是是否是利用Python,以至C编写代码,它都是一个很好的入门资本。

  差别块中的线程被摆设以差别的方法运转,会见差别的内存地区并在其他一些方面有所差别,本文次要引见简朴的入门以是我们将跳过这些细节。

  1、了解怎样考虑和设想并行的算法。由于一些算法是串行设想的,把这些算法并行化多是很艰难的。

  当内核启动时它会获得一个与之联系关系的网格,网格由块构成;块由线显现了一维CUDA网格。图中的网格有4个块。网格中的块数保留在一个特别的变量中,该变量能够在内核中经由过程gridDim.x间接会见,这里x是指网格的第一维度(在本例中是独一的维度)。二维网格也有经由过程y另有三维网格z变量来会见。到今朝2022年,还没有四维网格或更高的网格。在内核内部能够经由过程利用 blockIdx.x 找出正在施行的块,比方我们这个例子它将从 0 运转到 3。

  Numba并非独一的挑选。CuPy 供给了经由过程基于CUDA的而且兼容Numpy的初级函数,PyCUDA供给了对CUDA API更细粒度的掌握,英伟达也公布了官方CUDA Python。

  在每一个网格的块数超越硬件限定但显存中能够包容完好数组的状况下,能够利用一个线程来处置数组中的多个元素,这类办法被称为Grid-stride。除克制硬件限定以外,Grid-stride还受益于重用线程,如许能够将线程创立/烧毁开消降到最低。 Mark Harris 的文章 CUDA Pro Tip: Write Flexible Kernels with Grid-Stride Loops 具体引见这个办法,这里就不再引见了。

  本文中引见了Numba和CUDA的根底常识,我们能够创立简朴的CUDA内核,并将其从内存挪动到GPU的显存来利用它们。还引见了怎样利用Grid-stride手艺在1D和2D数组上迭代。

  2、进修怎样将CPU上的构造(比方向量和图象)映照到 GPU 上比方线程和块。轮回形式和帮助函数能够协助我们处理这个成绩。

  设置这些参数有一些”科学“和一些”艺术“硬件包罗哪些内容。 关于“科学”:(a)它们该当是 2 的倍数,凡是在 32 到 1024 之间,而且(b)它们该当都被利用以最大化占用率(有几线程同时处于举动形态 )。以是Nvidia 供给了一个能够协助计较这些的电子表格。() 关于“艺术”而言,没有甚么能够猜测内核的举动,因而假如真的想优化这些参数常见计较机硬件装备,需求按照差别的输入来阐发代码。 可是按照经历普通GPU 的“公道”线

  每一个线程独一索引的计较能够很快就会过时, Numba 供给了十分简朴的包装器 cuda.grid,它以网格维度作为独一参数挪用。 以是我们新的内核将以下:

  上面我们对两个数组乞降,这比对两个数字乞降庞大:假定每一个数组都有20个元素。如上图所示,我们能够用每一个块8个线程启动内核。假如我们期望每一个线程只处置一个数组元素,那末我们最少需求4个块。启动4个块,每一个块8个线个线程。

  在利用 Numba 时,我们另有一个细节需求留意: Numba 是一个 Just-In-Time 编译器,这意味着函数只要在被挪用时才会被编译硬件包罗哪些内容。因而计时函数的第一次挪用也管帐时编译步调,这凡是要慢很多。以是必需起首经由过程启动内核然后对其停止同步来编译代码,确保了下一个内核无需编译便可立刻运转,如许获得的工夫才是精确的。

  如许固然将每一个线程映照到数组中的每一个元素……可是如今我们碰到了一些线程会溢出数组的成绩,由于数组有 20 个元素,而 i 的最大值是 32-1。 处理计划很简朴:关于那些溢出线程,不要做任何工作!

  假如我们改动数组的巨细时会发作甚么? 我们这里不改动函数而变动网格参数(块数和每一个块的线程数),如许就相称于启动最少与数组中的元素一样多的线程。

  3、了解驱动 GPU 编程的异步施行模子。不只 GPU 和 CPU 互相独登时施行指令,GPU的流还许可多个处置流在统一个GPU上运转,这类异步性在设想最好处置流时十分主要。

  以是这里就需求停止同步,也就是挪用 cuda.synchronize()函数,这个函数将截至主机施行任何其他代码常见计较机硬件装备,直到 GPU 完成已在此中启动的每一个内核的施行。

  上图为简化的CPU架构(左)和GPU架构(右)。计较发作在ALU(算术逻辑单位)中,DRAM保留数据,缓存保留的数据能够更快地会见,凡是是容量更小。

  CUDA内核是由主机(CPU)启动的装备函数但它们是在GPU上施行的,GPU和CPU欠亨讯(除非我们让它们通讯)。因而当GPU内核被启动时,CPU将简朴地持续运转后续指令,不论它们是启动更多的内核仍是施行其他CPU函数。以是假如在内核启动前后别离挪用time.time(),则只得到了内核启动所需的工夫,而不是计较运转所需的工夫。

  我们的函数界说与一般的函数定界说不异,但挪用却略有差别。它在参数之前有方括号:add_scalars[1, 1](2.0, 7.0, dev_c)

  关于多线程处置,最需求弄分明是怎样将线程下标映照到数组下标(由于每一个线程要自力处置部门数据)常见计较机硬件装备。 threadIdx.x 从 0 运转到 7硬件包罗哪些内容,因而它们本人没法索引我们的数组,差别的块也具有不异的threadIdx.x。 可是他们有差别的blockIdx.x。 为了得到每一个线程的独一索引,我们需求组合这些变量:

  每一个块都有必然数目的线程,保留在变量blockDim.x中硬件包罗哪些内容。线程索引保留在变量 threadIdx.x 中,在这个示例中变量将从 0 运转到 7。

  在挪用内核之前,需求起首在装备上创立一个数组。假如想要显现返回值则需求将它复制回CPU。这里就有一个隐形的成绩:为何挑选float32(单精度浮点数)?这是由于固然大大都GPU都撑持双精度运算,但双精度运算的工夫多是单精度运算的4倍以至更长。以是最好风俗利用np.float32和lex64而不是float / np.float64和complex / np.complex128

  要对GPU的切当属性停止细粒度掌握,能够利用Nvidia供给的较初级此外官方CUDA Python包,代码以下:

  CUDA最后被设想为与C兼容厥后的版本将其扩大到c++和Fortran。在Python中利用CUDA的一种办法是经由过程Numba,这是一种针对Python的立即(JIT)编译器,能够针对gpu(它也针对cpu,但这不在我们会商的范畴内)。Numba为我们供给了一个能够间接利用Python子集,Numba将静态编译Python代码并运转它。固然它没有完成完好的CUDA API,但与cpu比拟它撑持的特征曾经能够协助我们停止并行计较的加快。

  在较新版本的 Numba 中能够会会收到一条正告硬件包罗哪些内容,指出我们利用内核利用了非装备上的数据。这条正告的发生的缘故原由是将数据从主机挪动到装备十分慢, 我们该当在一切参数中利用装备数组挪用内核。以是我们需求预先将数组从主机挪动到装备:

  GPU(图形处置单位)最后是为计较机图形开辟的,可是如今它们险些在一切需求高计较吞吐量的范畴无处不在。 这一开展是由GPGPU(通用GPU)接口的开辟完成的,它许可我们利用GPU停止通用计较编程。这些接口中最多见的是CUDA,其次是OpenCL和近来刚呈现的HIP。

  当我们在第一个示例中利用参数[1,1]启动内核时,我们报告CUDA用一个线程运转一个块。经由过程修正这两个值能够利用多个块和多现线程屡次运转内核。 threadIdx.x 和 blockIdx.x 每一个线程的独一标识。

  GPU 相对 CPU 的最大劣势是它们可以并行施行不异的指令。单个 CPU 内核将一个接一个地串交运转指令。在 CPU 长进行并行化需求同时利用其多个内核(物理或假造)。比方普通的计较机有 4-8 个内核,而GPU 拥无数千个计较中心。有关这二者的比力,请拜见上面的图 1常见计较机硬件装备。 GPU 内核凡是速率较慢,且只能施行简朴的指令常见计较机硬件装备,但它们的数目凡是能够补偿这些缺陷。

  第一个需求留意的是内核(启动线程的GPU函数)不克不及返回值。以是需求经由过程通报输入和输出来处理这个成绩。这是C中常见的形式,但在Python中其实不常见。

免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186