Я использую findshift.cpp
из https://github.com/DIPlib/diplib/blob/master/src/analysis/findshift.cpp в коде ниже:
int main()
{
std::vector<double>x1 = {0,0,0,0,0 };
std::vector<double>y1 = { 0,0,0,0,0 };
double* xarr = &x1[0];
double* yarr = &y1[0];
double res=0.0;
std::string outputDir = "C:/me/openmp";
double t = -omp_get_wtime();
for (int k = 0; k < 600; k++) {
for (int j = 0; j < 100; j++) {
res = runFindShift(xarr, yarr, x1.size(), x1, y1);
}
std::string str1 = outputDir + "/" + "serial" + "k" + std::to_string(k) + ".csv";
const char *str = str1.c_str();
std::ofstream out(str);
out << res;
out.close();
std::cout << "k: " << k << ", res: " << res << std::endl;
}
t += omp_get_wtime();
res = 0.0;
double t2 = -omp_get_wtime();
#pragma omp for
for (int k = 0; k < 600; k++) {
for (int j = 0; j < 100; j++) {
res = runFindShift(xarr, yarr, x1.size(), x1, y1);
}
std::string str1 = outputDir + "/" + "ompFor" + "k" + std::to_string(k) + ".csv";
const char *str = str1.c_str();
std::ofstream out(str);
out << res;
out.close();
std::cout << "k: " << k << ", res: " << res << std::endl;
}
t2 += omp_get_wtime();
res = 0.0;
double t3 = -omp_get_wtime();
#pragma omp parallel for
for (int k = 0; k < 600; k++) {
for (int j = 0; j < 100; j++) {
res = runFindShift(xarr, yarr, x1.size(), x1, y1);
}
std::string str1 = outputDir + "/" + "ompParFor" + "k" + std::to_string(k) + ".csv";
const char *str = str1.c_str();
std::ofstream out(str);
out << res;
out.close();
std::cout << "k: " << k << ", res: " << res << std::endl;
}
t3 += omp_get_wtime();
std::cout << "t: " << t << std::endl;
std::cout << "t2: " << t2 << std::endl;
std::cout << "t3: " << t3 << std::endl;
return 0;
}
, где runFindShift.cpp
:
double runFindShift(double*x, double*y, int arr_length, std::vector<double> xv, std::vector<double>yv)
{
cv::Mat A(arr_length, 1, CV_64F);
std::memcpy(A.data, x, arr_length * 1 * sizeof(double));
cv::Mat B(arr_length, 1, CV_64F);
std::memcpy(B.data, y, arr_length * 1 * sizeof(double));
dip::Image inputA(xv.data(), { xv.size() });
dip::Image inputB(yv.data(), { yv.size() });
dip::Image im1 = inputA / 255.0;
dip::Image im2 = inputB / 255.0;
im1.Squeeze();
im2.Squeeze();
double out = dip::FindShift(im1, im2, "MTS")[0];
return out;
}
Однако серийная версия и pragma omp for
работают около 8 секунд, в то время как pragma omp parallel for
работает около 15 секунд
Я полагаю, что проблема связана с double out = dip::FindShift(im1, im2, "MTS")[0];
, потому что, если я закомментирую это и заменю на double out =0.0
, затем серийный номер и pragma omp for
работает около 5 сек c, тогда как pragma omp parallel for
работает около 4 секунд
Более того, если я заменим res = runFindShift(xarr, yarr, x1.size(), x1, y1);
в main
следующим :
for (int m = 0; m < 1000000; m++) {
res = res + m;
}
тогда, последовательный и pragma omp for
занимает примерно 146 секунд, а pragma omp parallel for
приводит к огромному ускорению, так как это занимает всего 4 секунды
Есть ли способ, которым я могу получить openmp для ускорения даже при использовании dip::FindShift
?
EDIT
Новый код ниже:
main.cpp
:
int main()
{
std::vector<double>x1 = {0,0,0,0,0 };
std::vector<double>y1 = { 0,0,0,0,0 };
double res=0.0;
std::string outputDir = "C:/me";
double t = -omp_get_wtime();
for (int k = 0; k < 600; k++) {
for (int j = 0; j < 100; j++) {
res = runFindShift(x1, y1);
}
}
t += omp_get_wtime();
res = 0.0;
double t3 = -omp_get_wtime();
#pragma omp parallel for
for (int k = 0; k < 600; k++) {
for (int j = 0; j < 100; j++) {
res = runFindShift(x1, y1);
}
}
t3 += omp_get_wtime();
std::cout << "t: " << t << std::endl;
std::cout << "t3: " << t3 << std::endl;
return 0;
}
runFindShift.cpp
:
double runFindShift(std::vector<double>& xv, std::vector<double>& yv)
{
dip::Image inputA(xv.data(), { xv.size() });
dip::Image inputB(yv.data(), { yv.size() });
dip::Image im1 = inputA / 255.0;
dip::Image im2 = inputB / 255.0;
im1.Squeeze();
im2.Squeeze();
double out = dip::FindShift(im1, im2, "MTS")[0];
return out;
}
последовательное время равно 4,3 сек c, а pragma omp parallel for
равно 12,3 сек c.