簡體   English   中英

如何用SSE來優化矩陣乘以3乘以3的矩陣?

[英]How to optimize a matrix 3 by 3 multiplication with a point with SSE?

我必須在圖像的每個點上應用變換矩陣才能獲得新的點坐標。

為此,我創建了一個自定義Matrix3by3類,其中包含大小為9的浮點數組。

為了將矩陣應用於每個點,首先我創建了這個函數:

constexpr auto apply_matrix(const Matrix3by3 & m, const Vec2i & p) -> Vec2f
{
  const auto x = m.at(0, 0) * p.x + m.at(0, 1) * p.y + m.at(0, 2);
  const auto y = m.at(1, 0) * p.x + m.at(1, 1) * p.y + m.at(1, 2);
  const auto z = m.at(2, 0) * p.x + m.at(2, 1) * p.y + m.at(2, 2);

  return { x / z, y / z };
}

如您所見,由於我的2D圖像中沒有z值,因此該函數將執行簡單的矩陣乘法而不進行最后的乘法。

這很好用,但是由於這部分代碼是熱代碼,因此我正在嘗試對其進行優化,因此我為其創建了SSE版本:

constexpr auto apply_matrix(const Matrix3by3 & m, const Vec2i & p) -> Vec2f
{
  using SSEVec3 = union {
    struct
    {
      float z, y, x;

    };
    __m128 values_ = _mm_setzero_ps();
  };

  const auto mvec1 = _mm_set_ps(0, m.at(0, 0), m.at(0, 1), m.at(0, 2));
  const auto mvec2 = _mm_set_ps(0, m.at(1, 0), m.at(1, 1), m.at(1, 2));
  const auto mvec3 = _mm_set_ps(0, m.at(2, 0), m.at(2, 1), m.at(2, 2));

  const auto pvec1 = _mm_set1_ps(static_cast<float>(p.x));
  const auto pvec2 = _mm_set1_ps(static_cast<float>(p.y));

  auto result = SSEVec3{};
  result.values_ = _mm_add_ps(_mm_add_ps(_mm_mul_ps(mvec1, pvec1), _mm_mul_ps(mvec2, pvec2)), mvec3);

  return { result.x / result.z, result.y / result.z };
}

這也可以,但是比第一個版本慢,並且由於我正在學習SSE,因此我無法確切知道為什么會這樣。

我的第二個版本的想法是並行執行x,y和z值的計算。

所以,這就是我的問題,為什么SSE版本的速度較慢,我如何優化它以使其盡可能快?

謝謝!

通常, 僅優化需要優化的內容 ,而不優化您認為需要的內容。

(原始)代碼中最糟糕的一點可能是重復的除法 ,而您的“優化”根本沒有幫助。 將浮點數或雙精度數相除要比此代碼中的所有其他方法差得多,因此,最佳的優化方法是通過將1 / z(除以一次 )計算為一個輔助變量,然后將其乘以兩倍來減小它。

但是-正如開頭所述-您可能不需要任何優化,或者可能需要其他優化。 測試,分析並尋找最慢的編碼。 猜測結果通常會浪費精力和不必要的代碼復雜性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM