天天看点

C++的 pack 与 unpack的方法

在使用 Cuda 的Thrust 进行加速时,需要将一些复杂信息从C++层传递到Cuda层,比如说 多个Device端的内存地址。

  • 一种常用的方式是,使用device_vector 与 STL vector 进行传递。
  • 本文使用另外一种方式,是将信息Pack成Device内存中的地址,传递到Cuda层后,再进行Unpack 处理。

下面的例子,表示的是将 std::vector<void*> 与 std::vector 进行 pack的方法,以及 unpack 的验证。

#include <stdio.h>
#include <vector>
#include <iostream>

void test_pack_unpack()
{
  // step1: Create Test Data
  std::vector<float> ratio;
  ratio.push_back(0.5f);
  ratio.push_back(0.5f);

  std::vector<void*> address;
  int temp_1 = 20;
  int temp_2 = 40;
  address.push_back(&temp_1);
  address.push_back(&temp_2);
  std::cout << "temp_1: " << &temp_1 << " temp_2 " << & temp_2 << std::endl;

  // step2: pack data to info_buffer
  int num = 2;
  std::vector<char> info_buffer(num * (sizeof(void*) + sizeof(float)));
  void* ptr = info_buffer.data();
  std::cout << "original pack address : " << (char**)ptr << std::endl;
  
  for (int i = 0; i < num; ++i)
  {
    memcpy(ptr, &address[i], sizeof(void*));
    ptr = (void*)((char*)(ptr)+sizeof(void*));
    ((float*)ptr)[0] = ratio[i];
    ptr = (void*)((char*)(ptr)+sizeof(float));
  }

  // step3: unpack data
  void* ptr_new = info_buffer.data();
  std::cout << "original unpack address : " << (char**)ptr_new << std::endl;
  for (int i = 0; i < num; ++i)
  {
    std::cout << " address : " << i << std::hex << (int)(*((char**)ptr_new)) << std::endl;
    ptr_new = (void*)((char*)(ptr_new)+sizeof(void*));
    std::cout << " ratio : " << i << *((float*)ptr_new) << std::endl;
    ptr_new = (void*)((float*)(ptr_new)+1);
  }

  std::cout << "end" << std::endl;
}

int main ()
{
  test_pack_unpack();
  return 0;
}
           

最终,输出的信息如下

temp_1: 00000000006FF664 temp_2 00000000006FF684
original pack address : 0000000000CE9C70
original unpack address : 0000000000CE9C70
address : 06ff664
ratio : 00.5
address : 16ff684
ratio : 10.5
ptr0000000000CE9C88
           

可以看到,pack 的 temp_1, temp_2的地址: 00000000006FF664, 00000000006FF684 正确的 unpack 得到了。

示例中,缺少的一步是 需要将 pack 的内存,使用CUDA 的API,变成Device Momery. 然后在 Device Momery中进行unpack.

继续阅读