如何在C++中用memcpy将unsigned long long复制到字节数组指定位置
用memcpy替换移位位运算优化字节复制
现有CUDA代码通过逐字节移位和位运算,把unsigned long long类型变量i的每个字节依次赋值给字节数组m的索引4到11位置,考虑到逐位操作可能拖慢性能,希望改用memcpy单次完成复制并测试速度。原代码如下:
int thread = blockIdx.x * blockDim.x + threadIdx.x + 0xeafe7436; uchar m[12]; uint res[4]; m[0] = (uchar)(thread & 0x000000ff); m[1] = (uchar)((thread >> 8) & 0x000000ff); m[2] = (uchar)((thread >> 16) & 0x000000ff); m[3] = (uchar)((thread >> 24) & 0x000000ff); for (unsigned long long i = 0; i < 0xffffffffffffffff; i++) { m[4] = (uchar)(i & 0x00000000000000ff); m[5] = (uchar)((i >> 8) & 0x00000000000000ff); m[6] = (uchar)((i >> 16) & 0x00000000000000ff); m[7] = (uchar)((i >> 24) & 0x00000000000000ff); m[8] = (uchar)((i >> 32) & 0x00000000000000ff); m[9] = (uchar)((i >> 40) & 0x00000000000000ff); m[10] = (uchar)((i >> 48) & 0x00000000000000ff); m[11] = (uchar)((i >> 56) & 0x00000000000000ff); md5(m, 12, res); }
替换方案
直接用memcpy将i的内存内容一次性复制到m数组的m+4位置即可,因为unsigned long long正好占8字节,完全覆盖m[4]到m[11]的8个元素。替换后的循环代码如下:
for (unsigned long long i = 0; i < 0xffffffffffffffff; i++) { memcpy(m + 4, &i, sizeof(unsigned long long)); md5(m, 12, res); }
关键注意点
- 字节序匹配:原代码的移位操作是把
i的最低字节(0-7位)存入m[4],次低字节存入m[5],直到最高字节(56-63位)存入m[11]——这和x86、ARM等主流架构默认的小端字节序完全一致。如果你的运行环境是小端系统,memcpy的结果和原代码完全等价;如果是大端系统,复制后的字节顺序会反转,需要额外处理。 - 进一步优化:原代码中
thread变量的4个字节拆分也可以用memcpy简化,一行代码替代四行移位操作:memcpy(m, &thread, sizeof(int)); - 性能测试:可以用CUDA事件计时对比两种实现的速度,在循环前后创建并记录
cudaEvent_t时间戳,计算总耗时即可。
内容的提问来源于stack exchange,提问作者Ömer Enes Özmen
相关产品推荐
相关产品推荐

