If the instructions are not in the same 8 byte alignment then there is no effect.Exophase said:"Look up BTB entry" per here of course meaning "checks if it's a hit", since most instructions have no rightful business being in the BTB. I don't know if the issue is limit in access rate of the BTB, because I think that a one cycle stall on the second branch wouldn't be as serious as you're making this sound. I think it's more likely a collision in one of the prediction arrays. I'm voting against the BTB because it's not direct mapped. But the global historical buffer would hurt you if the two branches go opposite directions and share common low-enough order bits. I'm going to assume that they went opposite directions because it doesn't make much sense otherwise. Of course, Thumb-2 aggravates the issue by having more significant low end PC bits, and ARM does say that the performance with Thumb-2 is worse.
Can you test to see if the penalty is the same regardless of whether or the instructions are in the same 8 byte alignment?
Code:
b 12345678
mov r0,r0 ;stall
b 12345678
add r0,r0,#0 ;no penalty
b 12345678
ldr r0,[sp,#0] ;stall
b 12345678
str r0,[sp,#0] ;no penalty
Yeah, section 5.4: "You can avoid certain code constructs to maximize branch prediction performance. For example: [...] Coding more than two likely taken branches per fetch. This can only happen in Thumb state. Unless used as a jump table where each branch is its own basic block, use NOPs for padding."Exophase said:What's really strange is there IS a section in the TRM addressing similar (but more mild) issues regarding branch proximity.
However, there is a penalty for coding two likely taken branches per fetch in ARM state, eg
Code:
beq 0x12345678
b 0x1234abcd
Code:
beq 0x12345678
add r0, r0, #0
b 0x1234abcd
Also the TRM neglects to mention that using MOV as a NOP is a bad idea.
Last edited by a moderator: