我们正在做一个高性能计算项目,它使用 MPI 作为并行计算框架。遗留平台上已经实现了一些算法。我们所做的是将原来的串行算法重写为基于 MPI 的并行版本。
我遇到了这个性能问题:当运行基于 MPI 的并行算法时,多个进程之间有很多通信开销。进程间通信由三个步骤组成:
- 进程 A 将一些 C++ 对象序列化为二进制格式。
- 进程 A 通过 MPI 向进程 B 发送二进制格式的数据。
- 进程 B 将二进制格式数据反序列化为 C++ 对象。
我们发现这些通信步骤,尤其是序列化/反序列化步骤,会花费大量时间。我们如何处理这个性能问题?
顺便说一句,在我们的 C++ 代码中,我们使用了很多 STL,它比 C 类结构更复杂。
PS我现在通过编写代码遍历对象的所有字段并将它们按顺序复制到字节数组中来执行此操作(序列化)。
为了演示我在做什么,有一个代码片段。请注意,这只是一个单一的特征构建过程:
sic::GeometryFeature *ptFeature =
(GeometryFeature *) outLayer->getFeature(iFeature);
sic::Geometry* geom = ptFeature->getGeometry();
std::string geomClassName = geom->getClassName();
sic::Geometry* ptGeom = geom;
unsigned char *wkbBuffer = NULL;
OGRGeometry * gtGeom = NULL;
if (geomClassName == "Point") {
ptGeom = new sic::MultiPoint();
((sic::MultiPoint *) ptGeom)->insert(geom);
gtGeom = new OGRMultiPoint();
int wkbSize = ((sic::MultiPoint *) ptGeom)->WkbSize();
wkbBuffer = (unsigned char *) malloc(wkbSize);
((sic::GeometryCollection *) ptGeom)->exportToWkb(sic::wkbNDR,
wkbBuffer, wkbMultiPoint);
}
} else if (...) {
......
}
gtGeom->importFromWkb(wkbBuffer);
free(wkbBuffer);
assert(gtGeom);
OGRFeature * poFeature = OGRFeature::CreateFeature(
poLayer->GetLayerDefn());
poFeature->SetGeometry(gtGeom);
还有更多关于我在做什么序列化对象:
unsigned char *bytes = (unsigned char *) malloc(size);
size_t offset = 0;
size_t type_size = sizeof(OGRwkbGeometryType);
OGRwkbGeometryType type = layer->GetGeomType();
memcpy(bytes + offset, &type, type_size);
offset += type_size;
size_t count_size = sizeof(int);
int count = layer->GetFeatureCount();
memcpy(bytes + offset, &count, count_size);
offset += count_size;
layer->ResetReading();
for (OGRFeature *feature = layer->GetNextFeature(); feature != NULL;
feature = layer->GetNextFeature()) {
OGRGeometry *geometry = feature->GetGeometryRef();
if (geometry) {
geometry->exportToWkb(wkbNDR, bytes + offset);
offset += geometry->WkbSize();
} else {
(*(int *) (bytes + type_size))--;
}
OGRFeature::DestroyFeature(feature);
}
return bytes;
任何评论将不胜感激。谢谢!