您好,登錄后才能下訂單哦!
本篇內容介紹了“C++如何將計算從運行時移動到編譯時”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
Per.11:將計算從運行時移動到編譯時
為了減少代碼大小和執行時間。通過常量避免數據競爭。為了在編譯時捕捉錯誤(同時消除錯誤處理代碼)
Example(示例)
double square(double d) { return d*d; }
static double s2 = square(2); // old-style: dynamic initialization
constexpr double ntimes(double d, int n) // assume 0 <= n
{
double m = 1;
while (n--) m *= d;
return m;
}
constexpr double s3 {ntimes(2, 3)}; // modern-style: compile-time initialization
向s2初始化這樣的代碼很常見,特別是比square稍微復雜一點初始化代碼。然而,和s3的初始化相比,存在兩個問題:
we suffer the overhead of a function call at run time
我們需要負擔執行時的函數調用所需的代價。
s2 just might be accessed by another thread before the initialization happens.
在被初始化之前,s2可能被另外的線程訪問。
Note: you can't have a data race on a constant.
注意:常量不會發生數據競爭。
Example(示例)
考慮一種提供一個存儲小對象于自身,存儲大對象于堆的句柄。
constexpr int on_stack_max = 20;
template<typename T>
struct Scoped { // store a T in Scoped
// ...
T obj;
};
template<typename T>
struct On_heap { // store a T on the free store
// ...
T* objp;
};
template<typename T>
using Handle = typename std::conditional<(sizeof(T) <= on_stack_max),
Scoped<T>, // first alternative
On_heap<T> // second alternative
>::type;
void f()
{
Handle<double> v1; // the double goes on the stack
Handle<std::array<double, 200>> v2; // the array goes on the free store
// ...
}
假設Scoped和On_head提供了兼容的用戶接口。這里我們在編譯時計算最優的類型。類似的技術可以用于選擇最優的函數調用。
Note(注意)
理想狀態時{不要}試圖在運行時執行每一件事。顯然由于大多數計算依靠輸入信息,所以無法移動到編譯時計算,但是復雜的編譯時計算會嚴重的增加編譯時間并使調試復雜化。甚至可能由于引入編譯時計算使代碼變慢。不可否認,這種情況非常少見,但是通過將一個通常的計算強制分為獨立的最優化子計算過程,有可能使指令緩存效率變低。
Enforcement(實施建議)
Look for simple functions that might be constexpr (but are not).
尋找可以(但是沒有)定義為constexpr的簡單函數。
Look for functions called with all constant-expression arguments.
尋找使用常量表達式參數調用的函數。
Look for macros that could be constexpr.
尋找可以定義為constexpr。
“C++如何將計算從運行時移動到編譯時”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。