加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

CUDA内核在2个不同的GPU上产生不同的结果(GeForce 8600M GT与Qua

发布时间:2020-12-16 06:55:03 所属栏目:百科 来源:网络整理
导读:我一直在研究AES CUDA应用程序,我有一个在GPU上执行ECB加密的内核.为了确保在并行运行时不修改算法的逻辑,我发送NIST提供的已知输入测试向量,然后从主机代码将输出与NIST提供的已知测试向量输出与断言进行比较. 我在我的NVIDIA GPU上运行了这个测试,这是一个
我一直在研究AES CUDA应用程序,我有一个在GPU上执行ECB加密的内核.为了确保在并行运行时不修改算法的逻辑,我发送NIST提供的已知输入测试向量,然后从主机代码将输出与NIST提供的已知测试向量输出与断言进行比较.
我在我的NVIDIA GPU上运行了这个测试,这是一个8600M GT.这是在 Windows 7下运行的,驱动程序版本是3.0.在这个场景下,一切都很完美,断言成功.

现在,当应用程序在Quadro FX 770M上运行时.启动相同的应用程序,发送相同的测试向量,但获得的结果不正确,断言失败!!这在Linux上运行,具有相同的驱动程序版本
内核由256个线程执行.在内核中并且为了跳过算术,使用了256个元素的预先计算的查找表.这些表最初加载在全局内存中,256个线程中的1个线程启动内核,在加载查找表的1个元素时进行协调,并将元素移动到共享内存中的新查找表中,从而减少访问延迟.

最初,我考虑过GPU之间的时钟速度差异导致的同步问题.因此,可能是线程使用的值仍然没有加载到共享内存中,或者某些值仍未处理,从而产生输出
搞砸了,最后弄错了.

在这里声明了已知的测试向量,所以基本上它们被发送到AES_set_encrption,它负责设置内核

void test_vectors ()
{ 

  unsigned char testPlainText[]  = {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a}; 
     unsigned char testKeyText[] =  {0x60,0xeb,0x10,0x15,0xca,0x71,0x2b,0xae,0xf0,0x85,0x7d,0x77,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0xa3,0x09,0x14,0xdf,0xf4};
     unsigned char testCipherText[] = {0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c,0x06,0x4b,0x5a,0xb1,0x81,0xf8};

 unsigned char out[16] = {0x0};
     //AES Encryption
AES_set_encrption( testPlainText,out,16,(u32*)testKeyText);

 //Display encrypted data
 printf("n  GPU Encryption: "); 
 for (int i = 0; i < AES_BLOCK_SIZE; i++)
         printf("%x",out[i]);

 //Assert that the encrypted output is the same as the NIST testCipherText vector 
 assert (memcmp (out,testCipherText,16) == 0);
}

在这里,设置功能负责分配内存,调用内核并将结果发送回hos.请注意我在发送回主机之前已经进行了syncrhonize,所以在这一点上应该完成一切,这让我觉得问题出在内核中.

__host__ double AES_set_encrption (... *input_data,...*output_data,.. input_length,... ckey )

 //Allocate memory in the device and copy the input buffer from the host to the GPU
  CUDA_SAFE_CALL( cudaMalloc( (void **) &d_input_data,input_length ) ); 
  CUDA_SAFE_CALL( cudaMemcpy( (void*)d_input_data,(void*)input_data,input_length,cudaMemcpyHostToDevice ) ); 

     dim3 dimGrid(1);
     dim3 dimBlock(THREAD_X,THREAD_Y); // THREAD_X = 4 & THREAD_Y = 64
  AES_encrypt<<<dimGrid,dimBlock>>>(d_input_data);

     cudaThreadSynchronize();

     //Copy the data processed by the GPU back to the host 
  cudaMemcpy(output_data,d_input_data,cudaMemcpyDeviceToHost);

  //Free CUDA resources
  CUDA_SAFE_CALL( cudaFree(d_input_data) );
}

最后在内核中我有一组计算的AES轮次.因为我认为同步问题是在内核中我设置__syncthreads();在每轮或计算操作之后,确保所有线程同时移动,以便不评估未计算的值migth ..但仍然没有解决问题..

这是我使用8600M GT GPU工作正常时的输出:

AES 256位密钥

NIST测试向量:

PlaintText:6bc1bee22e409f96e93d7e117393172a

关键词:603deb1015ca71be2b73aef0857d7781

CipherText:f3eed1bdb5d2a03c64b5a7e3db181f8

GPU加密:f3eed1bdb5d2a03c64b5a7e3db181f8

测试状态:通过

这是我使用Quadro FX 770M时失败!!

AES 256位密钥
NIST测试向量:

PlaintText:6bc1bee22e409f96e93d7e117393172a

关键词:603deb1015ca71be2b73aef0857d7781

CipherText:f3eed1bdb5d2a03c64b5a7e3db181f8

GPU加密:c837204eb4c1063ed79c77946893b0

通用断言memcmp(out,16)== 0抛出了一个错误

测试状态:失败

即使处理相同的内核,2个GPU计算不同结果的原因可能是什么?
我将非常感谢您提供的任何暗示或疑难解答,或任何步骤以解决此问题

提前致谢!!

解决方法

免责声明:我对AES加密一无所知.

你用双精度?你可能知道,但只是为了确定 – 我相信你使用的两张卡都是计算能力1.1,它不支持双精度.也许卡或平台以不同的方式转换为单精度……?谁知道?说实话,IEEE浮点偏差很明确,所以我会感到惊讶.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读