天天看點

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.

繼續閱讀