【问题标题】:What is the fastest way to send vector<vector<double>> from one process created in x86 platform to another process built in x64将 vector<vector<double>> 从在 x86 平台中创建的一个进程发送到在 x64 中构建的另一个进程的最快方法是什么
【发布时间】:2018-08-11 11:14:04
【问题描述】:

我有两个进程 p1p2p1 内置于 x86,p2 内置于 x64 平台,使用 (Visual Studio 2013/MFC/C++)

p1 计算结果并将其保存在 std::vector&lt;std::vector&lt;double&gt;&gt; data。 我希望尽快将这个datap1 转移到p2std::vector&lt;std::vector&lt;double&gt;&gt; data

我使用boost::archive::text_iarchive 将其写入文本文件。由于它是跨平台兼容的,我可以在 p2 中使用boost::archive::text_oarchive 阅读它。但是它需要太多时间,因为它涉及磁盘读取和写入。所以我需要更好的方法来完成这项工作。

请建议我一些更快的跨平台数据传输方法。如果有人也可以提供一些代码,我将不胜感激。

【问题讨论】:

  • 我假设在一台机器内?共享内存最有可能。或者如果需要文件,至少用二进制而不是文本编写它。或者因为它在向量内部,可能只是通过管道推动
  • 你可能想看看cereal
  • 如果您的二维数组是矩形,则将其转换为一维数组,并在文件映射对象中为其分配存储空间(请参阅Creating a File Mapping Object)。如果您的二维数组是锯齿状的,您只能在文件映射对象中存储单独的行。确保您还在文件映射对象中保留描述数据(尺寸、大小)的元数据。文件映射对象可以映射到任意位数的进程中,而无需实际复制数据。
  • 我假设在一个 beowulf 集群中?使用 IPC,可能通过 TCP/IP 套接字,并以二进制形式发送数据。
  • 看看保存问题的答案。 v v

标签: c++ visual-studio boost mfc


【解决方案1】:

正如其他人已经提到的,最快和直接的方法是使用共享内存。以下是 Posix 系统的示例。

服务器创建一个共享内存对象,并通过将每个子向量写入长度加项的形式将向量序列化到内存中。

接收方打开共享内存对象,再次将内存反序列化为vector对象的vector。

发件人:

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#include <vector>
#include <algorithm>

static const std::vector<std::vector<double>> vec = {
  { 1.0, 1.1, 1.2 },
  { 2.0, 2.1 },
  { 3.0, 3.1, 3.2, 3.3 },
};

int main(int argc, char *const argv[])
{
  uint64_t vecsSize = 0;
  for (const auto& v : vec) {
    vecsSize += sizeof(double) * v.size() + sizeof(uint64_t);
  }

  // create a file of size 'vecsSize'
  int fd = open("VEC", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  lseek(fd, vecsSize - 1, SEEK_SET);
  write(fd, "", 1);
  lseek(fd, 0, SEEK_SET);

  // memory map the file into the process and copy the data into it
  uint8_t* ptrFile = reinterpret_cast<uint8_t*>(mmap(0, vecsSize, PROT_WRITE, MAP_SHARED, fd, 0));
  uint8_t* ptr = ptrFile;
  for (const auto& v : vec)
  {
    reinterpret_cast<uint64_t*>(ptr)[0] = v.size();
    ptr += sizeof(uint64_t);

    std::copy(v.begin(), v.end(), reinterpret_cast<double*>(ptr));
    ptr += sizeof(double) * v.size();
  }

  munmap(ptrFile, vecsSize);
  close(fd);
  return 0;
}

接收者:

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#include <iostream>
#include <vector>
#include <algorithm>

template<class T>
inline std::ostream& operator<< (std::ostream& o, std::vector<T> const& v) {
  for (auto const& i : v)
    o << i << " ";
  o << std::endl;
  return o;
}

static std::vector<std::vector<double>> vec;

int main(int argc, char *const argv[])
{
  int fd = open("VEC", O_RDONLY, S_IRUSR | S_IWUSR);

  struct stat fileStat = { 0 };
  fstat(fd, &fileStat);

  uint64_t vecsSize = static_cast<uint64_t>(fileStat.st_size);
  uint8_t* ptrFile = reinterpret_cast<uint8_t*>(mmap(0, vecsSize, PROT_READ, MAP_SHARED, fd, 0));

  uint8_t* ptr = ptrFile;
  while (ptr < ptrFile + vecsSize)
  {
    uint64_t vecSize = reinterpret_cast<uint64_t*>(ptr)[0];
    ptr += sizeof(uint64_t);

    std::vector<double> v(
      reinterpret_cast<double*>(ptr),
      reinterpret_cast<double*>(ptr) + vecSize);
    ptr += sizeof(double) * vecSize;

    vec.emplace_back(v);
  }

  munmap(ptrFile, vecsSize);
  close(fd);

  std::cout << vec;
  return 0;
}

【讨论】:

  • 这当然不是最快的方法,正如问题所要求的那样。最快的方法是在共享内存中构建向量的内存支持。您可以将自定义分配器传递给任何标准容器来实现这一点。
  • 感谢大家分享您宝贵的cmets。
猜你喜欢
  • 1970-01-01
  • 2022-01-24
  • 2011-12-15
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多