虽然一个线程块可以包含线程的数量受到限制,但是一个kernel可以包括多个大小相同的线程块,因此kernel中的总线程数就等于每个块中线程的数量乘以线程块的数量。线程块之间是相互独立的,它们可以并行的执行,也可以顺序的串行执行。这就使得线程块可以在多个处理器核之中按照任意顺序调度,从而使得开发具有很强的灵活性和可编程性。并且这样线程块的数量就可以根据需要处理数据块的大小决定,而不是由系统中处理器核的个数决定,也就是说线程块的总数量可以大于多核处理器的总数量。因此kernel中可以具有大量线程块,从而具有极高的线程数量。不过因为线程块之间执行具有不确定性,所以不同线程块的线程之间不能够进行同步操作[6]。
在CUDA架构下,最小的执行单位是线程(thread)。多个线程可以组成一个线程块(block)。一个线程块中的线程能存取同一块共享内存,而且可以快速进行同步的动作。每一个线程块所能包含的线程数目是有限的(512或1024)。执行相同内核函数的线程块可以组成栅格(grid)。不同线程块中的线程无法存取同一个共享的内存,因此无法直接通信或进行同步。因此,不同线程块中的线程能合作的程度是不高的。不过,可以充分利用这个模式,取消CUDA实际上能够并行执行的线程数目限制。不同的栅格则可以执行不同的程序(即Kernel,内核函数)。栅格、线程块和线程之间的关系如图2.2所示。
图 2.2 栅格、线程块和线程之间的关系
每个线程自身都有一块32 bit大小的寄存器(register)和本地存储器(local memory)。同一个线程块中的每个线程则有共享的一块共享存储器(shared memory)。另外,所有的线程都共享一块常量存储器(constant memory)、全局存储器(global memory)和纹理存储器(texture memory)。不同的栅格文护各自不同的常量存储器、全局存储器、和纹理存储器[5]。CUDA的内存模型如图2.3所示。
图2.3 CUDA的内存模型3 AES加密算法
3.1 AES算法背景
1997年9月12日NIST正式征集算法,要求AES算法定义一个非保密的、算法公开的、无版税的、可在全球使用的对称分组密码,至少支持128比特长度的分组,支持128、192和256比特密钥长度。 2000年5月15日第二轮公开分析阶段结束,NIST认为Rijndael算法汇聚了安全、性能、效率、易用和灵活等优点,是AES最合适的选择。2000年10月2日NIST宣布最终选择Rijndael作为建议的AES,并于2001年7月正式投入使用。2001年11月26日NIST以美国联邦信息处理标准出版物197(FIPS PUB 197)将Rijndael作为AES规范发布[7]。
3.2 AES加密算法说明
3.2.1 AES算法特点
AES算法是一种循环分组密码算法。虽然Rijndael算法的分组长度和密钥长度可以独立的指定为128bit、192bit或256bit,但在FIPS PUB 197中规定AES只可以用于处理128bit的分组,密钥长度可以是128bit、192bit或256bit,分别称为AES-128、AES-192和AES-256。AES加密的轮数是一个变量,主要依赖于密钥长度,所有的运算都将在一个4×4字节的模块上进行。每轮包括4个顺序步骤:轮密钥加,字节代替,行移位,列混合。在加密以前,我们必须使用密钥扩展算法扩展密钥[8]。
明文分组要经过多次变换操作才能形成密文分组,算法每次操作的中间结果称为状态(State),各种变换都在状态上进行。状态可以用字节为元素组成二文数组阵列,共4行,Nb列,Nb等于数据块长度除以32。密钥的设计类似二文字节数组,也是4行,Nk列,且Nk等于密钥块的长度除以32。AES算法使用的是圈变换,其变换的轮数Nr由Nb和Nk共同决定,如图3.1所示: 高并行度的信息加解密算法研究(4):http://www.751com.cn/jisuanji/lunwen_7514.html