Mam funkcję w następujący sposób, nazywa się ją wiele razy, co powoduje, że mój program działa powoli. Czy istnieje sposób na jej optymalizację? Na przykład za pomocą instrukcji SIMD lub innych technik. Funkcja getray() służy do pobrania zapytania vector-2 wektor-2 z wstępnie obliczonej tabeli przeglądowej. Został skompilowany w Visual-studio-2013, a docelową konfiguracją jest maszyna x64.Optymalizacja funkcji C++
Nawiasem mówiąc, pętla for, która wywołuje tę funkcję wiele razy, jest już zoptymalizowana za pomocą OpenMP.
Dziękuję bardzo.
bool warpPlanarHomography(
const Eigen::Matrix3d& H_camera2_camera1
, const cv::Mat& image1
, const cv::Mat& image2
, FisheyeCameraUnified& cam1
, FisheyeCameraUnified& cam2
, const Eigen::Vector2i& patchCenter
, const int patchSize
, Eigen::Matrix<unsigned char, 7, 7>& patch1)
{
const int patchSize_2 = 3;
for (int v = 0; v < patchSize; ++v) // row
{
for (int u = 0; u < patchSize; ++u)
{
Eigen::Vector2i p1 = Eigen::Vector2i(u - patchSize_2, v - patchSize_2).cast<int>() + patchCenter;
if (p1(0, 0) < 0 || p1(1, 0) < 0 || p1(0, 0) >= image1.cols || p1(1, 0) >= image1.rows) return false;
Eigen::Vector3d ray1;
cam1.getRay(p1(1, 0), p1(0, 0), ray1);
Eigen::Vector2d p2;
if (!cam2.project(H_camera2_camera1 * ray1, p2))
{
return false;
}
if (p2.x() < 0.0 || p2.x() >= image2.cols - 1 ||
p2.y() < 0.0 || p2.y() >= image2.rows - 1)
{
return false;
}
getInterpolatedPixel(image2, p2, &patch1(v, u));
}
}
return true;
}
, gdzie funkcja projekt wygląda tak
bool FisheyeCameraUnified::project(const Eigen::Vector3d& ray, Eigen::Vector2d& pt)
{
double fx, fy, cx, cy, xi;
fx = m_K(0, 0);
fy = m_K(1, 1);
cx = m_K(0, 2);
cy = m_K(1, 2);
xi = m_xi;
double d = ray.norm();
double rz = 1.0/(ray(2) + xi * d);
// Project the scene point to the normalized plane.
Eigen::Vector2d m_d(ray(0) * rz, ray(1) * rz);
// Apply the projection matrix.
pt(0) = fx * m_d(0) + cx;
pt(1) = fy * m_d(1) + cy;
return true;
}
i getInterpolatedPixel() funkcji w następujący sposób
void getInterpolatedPixel(const cv::Mat& image, const Eigen::Vector2d& coords, unsigned char* pixel)
{
int ix = static_cast<int>(coords.x());
int iy = static_cast<int>(coords.y());
double dx = coords.x() - ix;
double dy = coords.y() - iy;
double dxdy = dx * dy;
const double w00 = 1.0 - dx - dy + dxdy;
const double w01 = dx - dxdy;
const double w10 = dy - dxdy;
const double w11 = dxdy;
const unsigned char* p00 = image.data + iy * image.step.p[0] + ix * image.channels();
const unsigned char* p01 = p00 + image.channels();
const unsigned char* p10 = p00 + image.step.p[0];
const unsigned char* p11 = p10 + image.channels();
for (int i = 0; i < image.channels(); ++i)
{
double value = w11 * p11[i] + w10 * p10[i] + w01 * p01[i] + w00 * p00[i];
pixel[i] = cv::saturate_cast<unsigned char>(value);
}
}
Jak powiedział pętlę w 'getInterpolatedPixel' to wąskie gardło, nie spróbujesz użyć OpenMP do tego? Czy OpenMP jest dla Ciebie opcją? Aby uzyskać proste użycie instrukcji SIMD, spróbuj [VC] (https://github.com/VcDevel/Vc). –
Nie próbowałem używać OpenMP do funkcji getInterpolatedPixel, ale próbowałem dla WarpPlanarHomography. Nie daje mi to żadnych korzyści. Sądzę, że powodem jest to, że pętla for jest mała, gdzie usprawnienia wydajności nie mogą zrekompensować kosztów ogólnych spowodowanych przez OpenMP. Myślę więc, że dobrym pomysłem byłoby zoptymalizowanie tej małej funkcji za pomocą SIMD i optymalizacja zewnętrznej dużej pętli for z OpenMP. Tak, dziękuję za informacje z biblioteki. Spróbuję. – Peidong
Myślę, że funkcja 'projektu' została pomieszana przez skopiowanie i wklejenie –