簡體   English   中英

同時將所有結構元素與標量相乘

[英]Simultaneously multiply all struct-elements with a scalar

我有一個代表向量的結構。 該向量由兩個1字節整數組成。 我使用它們將值保持在0到255之間。

typedef uint8_T unsigned char;

struct Vector
{
  uint8_T x;
  uint8_T y;
};

現在,我程序中的主要用例是將向量的兩個元素與32位浮點值相乘:

typedef real32_T float;

Vector Vector::operator * ( const real32_T f ) const {
  return Vector( (uint8_T)(x * f), (uint8_T)(y * f) );
};

這需要經常執行。 有沒有辦法可以同時執行這兩個乘法? 也許通過矢量化,上交所或類似的方式? 還是Visual Studio編譯器已經同時執行此操作?

另一個用例是在兩個向量之間進行插值。

Vector Vector::interpolate(const Vector& rhs, real32_T z) const
{
  return Vector(
        (uint8_T)(x + z * (rhs.x - x)),
        (uint8_T)(y + z * (rhs.y - y))
        );
}

這已經使用了優化的插值方法( https://stackoverflow.com/a/4353537/871495 )。

但是向量的值再次乘以相同的標量值。 有可能改善這些操作的性能嗎?

謝謝

(我正在將Visual Studio 2010與64位編譯器一起使用)

以我的經驗,Visual Studio(尤其是像VS2010這樣的較舊版本)並不能單獨進行很多矢量化處理。 他們在較新的版本中對其進行了改進,因此,如果可以,您可能會發現更改編譯器是否可以加快代碼的速度。

根據使用這些功能的代碼以及編譯器所做的優化,可能甚至不會使計算速度變慢。 函數調用和緩存未命中可能會造成更大的傷害。

您可以嘗試以下方法:

  • 如果尚未完成,請在頭文件中定義函數,以便編譯器可以內聯它們
  • 如果您在緊密的循環中使用這些函數,請嘗試在不進行任何函數調用的情況下“手動”執行計算(暫時公開變量),看看是否會造成速度差異)
  • 如果您有很多向量,請查看它們在內存中的布局方式。 連續存儲它們以最大程度地減少緩存未命中。
  • 為了使SSE真正運作良好,您必須一次處理4個值-因此將2個向量與2個浮點數相乘。 在一個循環中,使用2的步長並編寫一個靜態函數,該函數使用SSE指令一次計算2個向量。 由於向量不對齊(幾乎不會使用8位變量),因此代碼甚至可能比現在運行的速度慢,但是值得一試。
  • 如果適用並且不依賴於從floatuint8_t時發生的鉗位(例如,如果float處於[0,1]范圍內),請嘗試在各處使用float 這可以使編譯器做得更好。

您尚未展示完整的算法,但是整數和浮點數之間的轉換是非常慢的操作。 消除此操作,僅使用一種類型(如果可能,最好是整數)可以大大提高性能。

Alternatevly,你可以使用lrint()來執行轉換為解釋在這里

暫無
暫無

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

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