2012-04-17 103 views
1

使用方案我需要使用以下功能。 (所有的參數都是自然數[0,inf))做整數除法的最快方法是什麼?

(define safe-div 
    (lambda (num denom safe) 
    (if (zero? denom) 
     safe 
     (div num denom)))) 

但是,這個函數被調用的頻率很高,並且性能不夠好(速度明智)。 是否有更有效的方法來實現所需的行爲(num和denom的整數除法,如果denom爲零則返回安全值)?

筆記,我正在使用Chez計劃,但是這是用於只導入rnrs而不是全部Chez的庫。

+0

你確定你的問題在這裏嗎? 「安全」是做什麼的? – oobivat 2012-04-17 03:33:41

+0

安全是根據第一個問題的範圍[0,inf)的自然數,所以它什麼都不做 – 2012-04-17 03:46:11

+3

您是否編寫過一些測試來檢查此例程的速度,以及它與簡單整數除法的區別?有很多事情可能會有所作爲,但在調整之前,您肯定需要掌握性能。 – 2012-04-17 04:07:45

回答

6

爲獲得最佳性能,您需要儘可能接近芯片。像這樣的安全檢查是不會做到的,除非它們被計劃系統及時編譯成超高效的機器代碼。

我看到兩個選項。一種是在C(或彙編)中創建一個本地(即foreign)實現並調用它。這可能與將它打包爲lambda不兼容,但是再一次,lambda的動態特性導致符號效率,但不一定是運行效率。 (除了函數指針外,還有一個原因是lambda表達式在C中是不存在的,儘管它已經老了許多年。)如果你走這條路線,最好退一步看看更大的safe-div處理是一部分應該是原生的。如果周圍環境的一切仍然很緩慢,那麼在加速循環中心的劃分方面毫無意義。

假設被零除的情況預計很少見,另一種方法是僅使用div,並希望其實現速度很快。是的,這可能會導致零分,但當談到速度時,有時候最好是乞求寬恕而不是要求許可。換句話說,在分部之前跳過檢查,然後執行。如果失敗,方案運行時應該通過零故障捕獲除法,並且您可以爲其安裝一個exception handler。這會導致例外情況下的代碼變慢,而在正常情況下導致更快的代碼。希望這種折衷能夠取得業績。

最後,根據你的分割情況,乘以倒數可能會比執行實際的分割更快。這需要快速的相互計算或者修改早期的計算來直接產生相互作用。既然你在處理整數,倒數將存儲在定點上,這實質上是2^32 * 1/denom。將其乘以num並將其右移32位以獲得商。因爲現在有更多的處理器具有單週期乘法指令,但是除法在芯片上循環執行,這會慢得多,所以這可以成功贏得勝利。這可能是爲了你的需要矯枉過正,但在某些時候可能會有用。

相關問題