检查原来的Mat
首先是连续的,如果不是,则克隆它。
然后,只需获得:
原始
Mat
的
和保存的顺序,每一个如4个字节,在一个缓冲区的开始。然后从原始的Mat
的data
指针中追加适当的字节数并发送整个批次。
在接收端执行相反的操作...从缓冲区中读取前四个整数并创建相应大小的Mat
并将其余数据加载到其中。
@Miki提供了一个极好的,相关的答案here这表明大部分的上面建议的技术细节 - 在Mat2str()
和str2Mat()
专门研究。
我不会做太多的C++或MPI,我相信任何使用MPI或C++的人都可以收紧它,但以下工作原理和工作速度也非常快!
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <ctime>
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "mpi.h"
using namespace std;
using namespace cv;
const int MAXBYTES=8*1024*1024;
uchar buffer[MAXBYTES];
void matsnd(const Mat& m,int dest){
int rows = m.rows;
int cols = m.cols;
int type = m.type();
int channels = m.channels();
memcpy(&buffer[0 * sizeof(int)],(uchar*)&rows,sizeof(int));
memcpy(&buffer[1 * sizeof(int)],(uchar*)&cols,sizeof(int));
memcpy(&buffer[2 * sizeof(int)],(uchar*)&type,sizeof(int));
// See note at end of answer about "bytes" variable below!!!
int bytespersample=1; // change if using shorts or floats
int bytes=m.rows*m.cols*channels*bytespersample;
cout << "matsnd: rows=" << rows << endl;
cout << "matsnd: cols=" << cols << endl;
cout << "matsnd: type=" << type << endl;
cout << "matsnd: channels=" << channels << endl;
cout << "matsnd: bytes=" << bytes << endl;
if(!m.isContinuous())
{
m = m.clone();
}
memcpy(&buffer[3*sizeof(int)],m.data,bytes);
MPI_Send(&buffer,bytes+3*sizeof(int),MPI_UNSIGNED_CHAR,dest,0,MPI_COMM_WORLD);
}
Mat matrcv(int src){
MPI_Status status;
int count,rows,cols,type,channels;
MPI_Recv(&buffer,sizeof(buffer),MPI_UNSIGNED_CHAR,src,0,MPI_COMM_WORLD,&status);
MPI_Get_count(&status,MPI_UNSIGNED_CHAR,&count);
memcpy((uchar*)&rows,&buffer[0 * sizeof(int)], sizeof(int));
memcpy((uchar*)&cols,&buffer[1 * sizeof(int)], sizeof(int));
memcpy((uchar*)&type,&buffer[2 * sizeof(int)], sizeof(int));
cout << "matrcv: Count=" << count << endl;
cout << "matrcv: rows=" << rows << endl;
cout << "matrcv: cols=" << cols << endl;
cout << "matrcv: type=" << type << endl;
// Make the mat
Mat received= Mat(rows,cols,type,(uchar*)&buffer[3*sizeof(int)]);
return received;
}
int main (int argc, char *argv[])
{
// Initialise MPI
MPI::Init (argc,argv);
// Get our rank
int id = MPI::COMM_WORLD.Get_rank();
if(id==0)
{
// MASTER - wait to receive image from slave and write to disk for checking
Mat received=matrcv(1);
imwrite("received.jpg",received);
}else{
// Slave - read Mat from disk and send to master
Mat image=imread("image.jpg",IMREAD_COLOR);
matsnd(image,0);
}
// Terminate MPI
MPI::Finalize();
}
我把循环10,000次迭代左右:
matrcv()
,并花了1.9秒为10,000次重复。我无法比较,因为你没有显示任何时间。
所有cout
声明是硬左对齐的只是调试的东西,可以安全地删除。
注:
虽然我已经使用并测试上面,因为我已经了解到,字节数的我送的计算可能会在某些情况下(也许那里有对齐限制)不正确。如果您有兴趣,请检查this answer。
关键词:MPI,MPI_SEND,MPI_RECV,OpenCV的,垫,图像
请出示您已经使用转换为INT''**以及特定的测量,你认为是结果代码*慢*? – Zulan
我发布了代码 – RicUfa
我没有看到任何MPI或性能测量结果。 – Zulan