2017-11-18 173 views
0

我想用匯編語言編寫一秒延遲循環,但我不確定循環的計數是什麼,以便延遲1秒。如何在Assembly中爲延遲循環設置正確的時序?

這是我到目前爲止有:

MOV R1, #count 

DELAY_LOOP: 
      SUBS R1, R1, #1 

      BNE DELAY_LOOP 

我使用的是Beaglebone黑色。提前致謝!

+1

如果有可用的定時器中斷,請嘗試使用它。 – Thilo

+1

檢查時鐘速度以及您使用每條指令需要多少時鐘。然後劃分。或者,如果你懶惰並且不需要很高的精度,那麼在該處粘貼一個大數字,然後用手錶計時,然後將其縮小。 – Jester

+0

特別是在現代CPU中;對於不同的CPU,時鐘速度可以不同,和/或可以在CPU運行時改變(由於電源管理 - 例如,由Beaglebone Black使用的SoC支持的「動態CPU頻率縮放」功能);如果這些事情都不可能,那麼「隨機」進行循環的IRQ仍然需要比應有的更長的時間。由於這些原因,延遲循環幾乎總是一個錯誤,因爲確定正確的計數是不可能的(甚至當它不是一個可移植性和維護性災難的錯誤時)。您應該使用實際的硬件計時器。 – Brendan

回答

0

很難爲ARM獲得這種權利,尤其是在操作系統上運行此操作時。不可能是準確的。純粹的裸機,沒有中斷,你可以通過實驗手動調整它,但是如果你改變了對齊方式,那麼性能可能會發生很大的變化,這不僅是因爲大多數人會假設的緩存,而且還會影響到獲取線的位置和最佳點用於分支預測,如果存在分支預測以及它是如何實現的。我用這個確切的循環來證明這個問題有點微不足道。

這個問題不是ARM特有的任何事情流水線每次抓取事務往往要抓取多個指令,出於性能原因,抓取通常在對齊的邊界上,並且預取緩衝區中存在一個接收這些數據的水印確定何時執行下一個讀取操作,甚至這兩個指令在一個循環中的對齊取決於它們在哪裏可以對執行性能造成嚴重影響,基本上它執行兩個讀取行或每個循環一次,高速緩存在第一遍之後不相關,一個或兩個讀取行仍然可以訪問緩存。

但是,這一切都因建築而異。訪問和緩衝到管道,arm,x86,powerpc等中的Mips都有所不同,並且可能因該體系結構的rev或generation而每隔三年變化一次,規則可能會針對該核心的下一個版本進行更改

ARM和MIPS以及其他基於IP的內核(其中芯片供應商實現內存系統)可以具有相同的核心版本,但是芯片供應商或家族對芯片供應商或家族差異可能/將會影響性能,所以即使您得到了相當關閉在一個芯片上,保持 相同的對準,並且基於芯片供應商/存儲器側的 ,其他核心設置性能可以不同。將dram加入這個公式中,其中內存的性能不是非確定性的,你只是讓它變得更糟。

如果您回到預先流水線化的日子,一次執行一條指令,這是非常可預測的,常用的定時循環是使用較舊的PIC指令集完成的,極其可預測,並且並不少見請參閱使用定時循環而不是定時器。導致許多人嘗試這樣做後,他們在其他架構和體系結構上學習/在該架構上看到它(只是失敗)。

這是一個非常教育性的練習,我建議你試試看。使用定時器作爲參考,並在測試代碼之前和之後使用單個加載指令對其進行理想的取樣。如果你在操作系統上完成所有這些工作,可能會有足夠的噪音,你實際上並沒有看到差異的細節。您將創建其他循環竊取程序,並將其添加到總體計時中,特別是在測試代碼之前和之後獲取時間的呼叫。