![](/img/trans.png)
[英]How to properly take a boost::optional<std::chrono::duration> as a function parameter?
[英]counting duration with std::chrono gives 0 nanosecond when it should take long
我試圖使用std :: chrono計算for循環所花費的持續時間,但是即使我通過取消綁定值使循環花費更長的時間,它也給出了0納秒,這是代碼:
#pragma pack(1) // dont align let's let it take longer
struct Foo{
int x;
char c;
int z;
} ;
void take_time()
{
Foo f;
auto t1 = std::chrono::system_clock::now();
register int c = 0;
int x=0,y=0,z=1;
for (c=0;c<10000;c++){ // even if i put 1000000000 it will take 0 nanosec !!!!!
f.z = x+y;
f.z += z-x+y;
}
std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
}
輸出:
token time : 0
但是,當我使循環計數器的邊界值達到非常非常大的值時,它突然變得永遠永久! ,如果我把c <100000000花費了0納秒,但是如果我在右邊加上一個“ 0”,那將永遠花費!
答案 :正如WhiZTiM所說,編譯器正在刪除循環,因為它沒有任何用處(感謝gcc <3),但是我們真的不希望在測試算法時發現這種情況發生,因為在不同的編譯器上速度更快(不是這個特別的),為此,我們可以在循環中插入一個asm行。 asm("")
,一個空的asm,在循環中的任何位置。 這將告訴編譯器有些無法優化的底層操作! ,或者我們可以將volitile關鍵字用於循環中使用的任何變量,以防止編譯器進行與該變量相關的任何優化。 謝謝大家,我希望這會有所幫助
首先,使用初始化變量是一種罪過。
優化器肯定認為循環是無用的(實際上,循環中x
, y
, z
的值應該是什么); 並且沒有使用循環的結果(沒有副作用),因此它在生成的代碼中刪除了循環。
void take_time()
{
Foo f;
auto t1 = std::chrono::system_clock::now();
register int c = 0;
int x,y,z;
///// Result not used
for (c=0;c<10000;c++){ // even if i put 1000000000 it will take 0 nanosec !!!!!
f.z = x+y;
f.z += z-x+y;
}
/// We can discard the above
std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
}
順便說一句,不推薦使用那里的register
關鍵字。
對於GCC和clang,有一種方法可以“嚇跑”優化器,以免優化某些變量的使用。 我使用此功能:
template<typename T>
void scareTheOptimizer(T& x){
asm volatile("" :: "p"((volatile void*)&x) : "memory");
}
因此,當您在循環中調用它時,現在應該看到一些時間。
void take_time()
{
Foo f;
auto t1 = std::chrono::system_clock::now();
int c = 0;
int x=0,y=0,z=1;
for (c=0;c<10000;c++){
f.z = x+y;
scareTheOptimizer(f.z); /// <---- Added Here
f.z += z-x+y;
}
std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.