某處我已經讀過,現代英特爾處理器具有用於實現異常的低級硬件,大多數編譯器都利用它,使異常變得比使用變量返回結果狀態更快。C++返回值與異常性能
這是真的嗎?就返回狀態/響應狀態而言,異常比變量更快?閱讀堆棧溢出的話題似乎與此相矛盾。
謝謝
某處我已經讀過,現代英特爾處理器具有用於實現異常的低級硬件,大多數編譯器都利用它,使異常變得比使用變量返回結果狀態更快。C++返回值與異常性能
這是真的嗎?就返回狀態/響應狀態而言,異常比變量更快?閱讀堆棧溢出的話題似乎與此相矛盾。
謝謝
我不知道你在哪裏閱讀這個,但它肯定是不正確的。沒有硬件設計師會做出特殊情況,這種情況根據定義不常見,比正常情況下工作更快。另外請記住,根據TIOBE是最流行的系統語言的C,甚至不支持異常。對於ONE語言的異常處理來說,處理器的優化似乎極不可能,而編譯器的實現甚至不是標準化的。
即使異常情況比較快,您仍然不應該在預期目的之外使用它們,以免混淆世界上其他程序員。
不,沒有什麼比將變量粘貼到寄存器更快。即使有明確的硬件支持,異常仍然需要諸如內存訪問之類的東西。
C++異常大部分都不能以這種方式實現,因爲C++要求堆棧被解開並且對象被破壞。
請注意,術語「異常處理程序」中存在不明確之處。我相信你會發現硬件人們談論的異常時是指類似於:
這兩者都與C++的異常處理工具無關。作爲一個反例,我至少有一個軼事數據點,例外情況比返回代碼慢得多:那是在Intel硬件上,但是使用gcc 2.95和一個非常大的一組代碼以及一個非常大的異常表,這是在第一次拋出異常時構建的。隨後的例外情況很快,但到那時通常會造成損害。無可否認,gcc 2.95是相當古老的,但它應該足以讓你警惕關於C++異常處理速度的概括,即使在Intel硬件上也是如此。
即使它們速度更快,也不應該將它們用於非特殊情況以外的任何其他用途。如果你濫用它們,你會使你的程序更難調試。在gdb中,您可以執行「catch throw」,並輕鬆找出程序出錯的位置並拋出異常,但如果您將異常作爲常規處理的一部分拋出,則不會發生。
答案在技術上是正確的,但高度誤導。
問題的核心是觀察到異常是例外。他們通常不會發生。當您返回錯誤代碼時,情況並非如此。這種情況總是會發生的,即使沒有錯誤。在這種情況下,功能還有返回0
,或true
,或-1
,或...
現在,這意味着CPU和編譯器可以專門優化,通過異常失敗的功能。但是重要的是要實現他們優化哪些,這是非故障,非例外的情況 - 以特殊情況爲代價。
一旦我們意識到這一點,我們可以看看編譯器和CPU如何優化這種情況。一種常見的方法是將異常代碼與正常代碼分開。因此,該代碼通常不會在CPU緩存中結束,因此可以包含更多有用的代碼。實際上,異常代碼可能根本不會在RAM中結束,並保留在磁盤上。
另一個支持機制是CPU分支預測器。它會記住導致異常代碼的分支通常不會被採用,因此預測下次它們不被採用。編譯器甚至可以把它作爲提示。但是,這個提示功能在英特爾奔騰4之後就被拋棄了;現代CPU預測分支不夠好。
你的問題有點不清楚,因爲你通過實施例外意味着包括三個方面:
try
塊。這可以有沒有成本,但往往使throw
更昂貴。有a more specific question about this on SO。throw
。有a more specific question about this on SO。throw
到catch
,並將錯誤處理代碼(在catch
中)加載到CPU高速緩存中。您應該忽略這一成本,因爲如果使用狀態代碼而不是例外情況,則必須支付此成本。