C-Cortex-R5上的memcmp期间偶尔出现CPU暂停
我正在Cortex-R5(Ultrascale MpSoC)上运行一些测试。它基本上用一个硬件模块生成2个随机数,并在最后进行比较,以确保它们不是0,也不是相同的值C-Cortex-R5上的memcmp期间偶尔出现CPU暂停,c,arm,memcmp,C,Arm,Memcmp,我正在Cortex-R5(Ultrascale MpSoC)上运行一些测试。它基本上用一个硬件模块生成2个随机数,并在最后进行比较,以确保它们不是0,也不是相同的值 uint32_t status; const uint8_t zeros[32] = {0}; uint8_t bytes1[32] = {0}; uint8_t bytes2[32] = {0}; // (generate random numbers and put them in bytes1)
uint32_t status;
const uint8_t zeros[32] = {0};
uint8_t bytes1[32] = {0};
uint8_t bytes2[32] = {0};
// (generate random numbers and put them in bytes1)
// (generate random numbers and put them in bytes2)
printf("memcmp 0\n");
status = !memcmp(bytes1, bytes2, 32);
printf("memcmp 1\n");
status |= !memcmp(bytes1, zeros, 32);
printf("memcmp 2\n");
status |= !memcmp(bytes2, zeros, 32);
一些测试运行良好。一些执行在打印“memcmp0”后暂停(当它冻结时,总是在第一个memcmp处)
我试过几种方法:
- 当我打印字节1和字节2中的值时,它们实际上是不等于0且彼此不相等的随机数
- 在不同位置移动memcmp,或切换memcmp。它总是第一个结冰的
- 用自定义函数替换memcmp进行比较=>它永远不会冻结
- memcmp函数在代码的其他地方使用,在其他任何地方都不会冻结。也许区别在于,随机检查是memcmp期望不同值的唯一地方(在其他地方,它是为了确保函数产生预期的输出)
000064d0 <memcmp>:
64d0: 2a03 cmp r2, #3
64d2: b470 push {r4, r5, r6}
64d4: d912 bls.n 64fc <memcmp+0x2c>
64d6: ea40 0501 orr.w r5, r0, r1
64da: 4604 mov r4, r0
64dc: 07ad lsls r5, r5, #30
64de: 460b mov r3, r1
64e0: d120 bne.n 6524 <memcmp+0x54>
64e2: 681d ldr r5, [r3, #0]
64e4: 4619 mov r1, r3
64e6: 6826 ldr r6, [r4, #0]
64e8: 4620 mov r0, r4
64ea: 3304 adds r3, #4
64ec: 3404 adds r4, #4
64ee: 42ae cmp r6, r5
64f0: d118 bne.n 6524 <memcmp+0x54>
64f2: 3a04 subs r2, #4
64f4: 4620 mov r0, r4
64f6: 2a03 cmp r2, #3
64f8: 4619 mov r1, r3
64fa: d8f2 bhi.n 64e2 <memcmp+0x12>
64fc: 1e54 subs r4, r2, #1
64fe: b172 cbz r2, 651e <memcmp+0x4e>
6500: 7802 ldrb r2, [r0, #0]
6502: 780b ldrb r3, [r1, #0]
6504: 429a cmp r2, r3
6506: bf08 it eq
6508: 1864 addeq r4, r4, r1
650a: d006 beq.n 651a <memcmp+0x4a>
650c: e00c b.n 6528 <memcmp+0x58>
650e: f810 2f01 ldrb.w r2, [r0, #1]!
6512: f811 3f01 ldrb.w r3, [r1, #1]!
6516: 429a cmp r2, r3
6518: d106 bne.n 6528 <memcmp+0x58>
651a: 42a1 cmp r1, r4
651c: d1f7 bne.n 650e <memcmp+0x3e>
651e: 2000 movs r0, #0
6520: bc70 pop {r4, r5, r6}
6522: 4770 bx lr
6524: 1e54 subs r4, r2, #1
6526: e7eb b.n 6500 <memcmp+0x30>
6528: 1ad0 subs r0, r2, r3
652a: bc70 pop {r4, r5, r6}
652c: 4770 bx lr
652e: bf00 nop
000064d0:
64d0:2a03凸轮轴位置r2,#3
64d2:b470推送{r4,r5,r6}
64d4:d912 bls.n 64fc
64d6:ea40 0501或w r5、r0、r1
64da:4604 mov r4,r0
64dc:07ad lsls r5,r5,#30
64de:460b mov r3,r1
64e0:d120英国东北部6524
64e2:681d ldr r5[r3,#0]
64e4:4619 mov r1,r3
64e6:6826 ldr r6[r4,#0]
64e8:4620 mov r0,r4
64ea:3304加上r3,#4
64ec:3404增加r4,#4
64ee:42ae cmp r6,r5
64f0:d118英国东北部6524
64f2:3a04接头r2,#4
64f4:4620 mov r0,r4
64f6:2a03凸轮轴位置r2,#3
64f8:4619 mov r1,r3
64fa:d8f2 bhi.n 64e2
64fc:1e54接头r4、r2、1
64fe:b172 cbz r2,651e
6500:7802 ldrb r2[r0,#0]
6502:780b ldrb r3[r1,#0]
6504:429a cmp r2,r3
6506:bf08 it eq
6508:1864加法器r4,r4,r1
650a:d006 beq.n 651a
650c:e00c b.n 6528
650e:f810 2f01 ldrb.w r2[r0,#1]!
6512:f811 3f01 ldrb.w r3,[r1,#1]!
6516:429a cmp r2,r3
6518:d106英国东北部6528
651a:42a1 cmp r1,r4
651c:d1f7 bne.n 650e
651e:2000电影r0,#0
6520:bc70 pop{r4,r5,r6}
6522:4770 bx lr
6524:1e54潜艇r4、r2、1
6526:e7eb b.n 6500
6528:1ad0接头r0、r2、r3
652a:bc70 pop{r4,r5,r6}
652c:4770 bx lr
652e:bf00 nop
谢谢这听起来像是竞争条件错误、堆栈溢出之类的问题。这几乎肯定与memcmp无关,但与其他地方的一些无关的bug有关。如何填充这些数组?是否涉及中断或多个进程?我希望memcmp是内联的。您是否包含了?(当然也是stdio.h)@Lundin它们实际上是由可编程逻辑(PL)中的DMA填充的,其中随机发生器是。奇怪的是,当我在比较之前第一次打印bytes1和bytes2的值时,这个问题也出现了。。。之后怎么会有竞争条件?@wildplasser是的,我包括在内。1)在访问数据时,您需要保护数据不被DMA更新,否则会出现竞争条件地狱。2) 所有DMA缓冲区都必须是易失性的,否则编译器的优化器就可以自由地对它们执行非常奇怪的操作。这很可能是事实,因为像memcmp这样的函数都经过了大量优化,几乎总是内联的。