2016-07-07 60 views
0

我在編程raspbery pi model b ARM1176 bare metal(在彙編中和c)。我需要計算用於執行彙編代碼的時鐘週期。
我使用PMU櫃檯下面的代碼:ARM11中的PMU計數器

mov r0,#1 

MCR p15, 0, r0, c15, c12, 0 ; Write Performance Monitor Control Register 
    /* Reset Cycle Counter */ 

mov r0,#5 

MCR p15, 0, r0, c15, c12, 0 ; Write Performance Monitor Control Register 
    /* Meaure */ 

MRC p15, 0, r0, c15, c12, 1 @ Read Cycle Counter Register 

<MY CODES> 

MRC p15, 0, r1, c15, c12, 1 @ Read Cycle Counter Register 

由此看來,如果我有

add r3,#3 

代替我的代碼,我得到r1=8r0=0,這似乎是正確的,因爲ARM11具有8管線階段,它需要8個時鐘週期來執行它。

但是當我添加更多說明我越來越喜歡

add r3,#3 

add r4,#1 

r0=0,r1=97/96/94 (the result of r1 should also be constant!!!) 

荒謬的結果,我使用uart看到小型機寄存器的結果。

回答

0

好吧,看到相同的東西,這是非常有趣的。

@ nop 
.globl test 
test: 
    mov r0,#1 
    MCR p15, 0, r0, c15, c12, 0 
    mov r0,#5 
    MCR p15, 0, r0, c15, c12, 0 
    MRC p15, 0, r0, c15, c12, 1 

    add r3,#3 
    add r2,#1 

    MRC p15, 0, r1, c15, c12, 1 
    sub r0,r1,r0 
    bx lr 

我在C所以,如果我在代碼與R4淤泥下的測試將不得不將它保存與R2一團糟堆棧上調用此。如果沒有添加r2行,返回值爲8,add r2行返回值爲0x68,然後爲0x65。注意這是在一個pi零。所以有些時鐘比你的快一點。

請記住,這是從德拉姆運行,德拉姆是痛苦緩慢。所以你可能會看到一些。

代碼的初始對準:

00008024 <test>: 
    8024: e3a00001 mov r0, #1 
    8028: ee0f0f1c mcr 15, 0, r0, cr15, cr12, {0} 
    802c: e3a00005 mov r0, #5 
    8030: ee0f0f1c mcr 15, 0, r0, cr15, cr12, {0} 
    8034: ee1f0f3c mrc 15, 0, r0, cr15, cr12, {1} 
    8038: e2833003 add r3, r3, #3 
    803c: e2822001 add r2, r2, #1 
    8040: ee1f1f3c mrc 15, 0, r1, cr15, cr12, {1} 
    8044: e0410000 sub r0, r1, r0 
    8048: e12fff1e bx lr 

是的,如果我取消在.globl測試前的NOP,我註釋掉ADD R2我只有加R3作爲被測試的代碼,但nop推動整個代碼塊的對齊。與添加r3和沒有nop我得到8個計數與添加r3和nop我得到0x67計數。

所以我認爲這只是一個測量獲取的情況。我沒有啓用arm緩存,但可能會有更深的緩存或mmu或其他,因爲這個ram是在arm和gpu之間共享的。

如果我更進一步並取消nop的註釋,那麼add r3和add r2都是0x69計數。或者基本上等於或只比一個指令長,所以我們在那裏強制取回。

所以我在我的情況下,如果我增加更多的空指令因此計數的初始讀取時的8字邊界上對齊,和我有兩個指令被測

00008030 <test>: 
    8030: e3a00001 mov r0, #1 
    8034: ee0f0f1c mcr 15, 0, r0, cr15, cr12, {0} 
    8038: e3a00005 mov r0, #5 
    803c: ee0f0f1c mcr 15, 0, r0, cr15, cr12, {0} 
    8040: ee1f0f3c mrc 15, 0, r0, cr15, cr12, {1} 
    8044: e2833003 add r3, r3, #3 
    8048: e2822001 add r2, r2, #1 
    804c: ee1f1f3c mrc 15, 0, r1, cr15, cr12, {1} 
    8050: e0410000 sub r0, r1, r0 
    8054: e12fff1e bx lr 

我得到的8計數。我在第三條指令中添加了r3和兩個add r2s。仍然是8的計數。

如果我回到這裏至少有一部分是在不同的獲取線。

00008024 <test>: 
    8024: e3a00001 mov r0, #1 
    8028: ee0f0f1c mcr 15, 0, r0, cr15, cr12, {0} 
    802c: e3a00005 mov r0, #5 
    8030: ee0f0f1c mcr 15, 0, r0, cr15, cr12, {0} 
    8034: ee1f0f3c mrc 15, 0, r0, cr15, cr12, {1} 
    8038: e2833003 add r3, r3, #3 
    803c: e2822001 add r2, r2, #1 
    8040: ee1f1f3c mrc 15, 0, r1, cr15, cr12, {1} 
    8044: e0410000 sub r0, r1, r0 
    8048: e12fff1e bx lr 

我做三個奔跑在不改變任何東西,然後啓用L1緩存(指令),做三個跑我得到

00000068 
0000001D 
0000001D 
0000001F 
00000008 
00000008 

所以我認爲你是在處理與DRAM這是緩慢的,提取行,緩存未命中和命中以及由此產生的緩存行提取。

如果您希望看到執行您不會執行的指令所需的時鐘數,您不會有零等待狀態內存,除非您可以將整個代碼保存在l1緩存中進行測試。

我不認爲芯片上有sram,你可以用這種芯片/電路板來做這種事情,你最終會碰到dram,並且dram與gpu共享。所以基本上程序執行的時間不會是確定性的,並且與你的計算機或手機或其他CPU不是一個瓶頸已經很長時間了,它是坐在等待被饋送的數據或指令。