tomzbj 发表于 2022-2-10 19:09:30

再试STM32H750VB的dhrystone性能

一开始先不配PLL, 用64M HSI运行, AHB和各个APB都是1分频.测得24.22DMIPS,0.38DMIPS/MHz, 这也太差劲了吧.

把gcc优化参数从-Os改成-O3,则是37.92DMIPS, 0.59DMIPS/MHz, 好一些, 离标称的2.14DMIPS/MHz还差得远.

再打开cache试试, 加上两行:   SCB_EnableICache();   SCB_EnableDCache();再试, 这次-Os和-O3分别得到了1.19DMIPS/MHz和1.91DMIPS/MHz, 接近标称值了.

最后发现Makefile里指定的mmcpu还是cortex-m0, 改成m7再试, 这次-Os和-O3分别是1.37DMIPS/MHz和2.16DMIPS/MHz, 和标称值相符了.

然后把PLL配置成480M, AHB和各APB 2分频, 再试, 结果只有522DMIPS, 1.09DMIPS/MHz. 怎么又慢了?

AHB 1分频的话, 直接死机. 降频到200M左右, 则1分频可以运行, 也能测到2.16DMIPS/MHz的性能.那datasheet里标称的1027DMIPS是怎么测出来的?估计是默认的AXI SRAM拖后腿了, 得改成和CPU同频的DTCMRAM.

把dhrystone里用到的全局变量全部加上__attribute__((section(".DTCMRAM"))) ,再试,得到了569DMIPS, 1.19DMIPS/MHz, 只是稍微快了一点点.

估计还有什么地方得优化优化才行, 哪位熟悉的话指点一下?

amigenius 发表于 2022-2-14 23:59:48

刚才抽空测试了一下,Y版本的750,最高400M, 代码放内部Flash,变量默认全放DTCM,某DK5.3学习版Licence!学习版Licence!学习版Licence!, 选择AC6(CLANG),Ofast,开启REG优化。
刚开始,运行一次Dhrystone需要1.049ms, 非常精确的计时,开定时器的,加上开关定时器的损耗,误差不会超过1us。折算是542.56DMIPS, 即1.35DIMPS/M
然后不断的调整一下Cache参数,开关透写,改Flash延迟,改MPU的的设置,结果相差不大,各种设置在1.29~1.38DMIPS/M之间。各个优化等级尝试过,最快还是Ofast。折腾了半个小时,没多少效果,有点失望。难道H7真的就这个水平?
抽支烟放松一下,想这个Dhrystone是临时放在一个代码量1M左右的项目里测试的,而且Dhry_1.c,Dhry_2.c,e_lib.c分成3个文件,会否是因为编译器分配地址的时候把它们安置得太远,造成大量的Cache命中失败呢?于是立马把3个文件放到一个c里,按以往经验,同一C文件,为特别指定Section时,其地址分配是连续的,然后编译一时,奶奶的直接翻倍:
执行一次Dhrystone:0.489ms, 1163.9DMIPS,2.9DMIPS/M, 我都有点不相信了,改回分开3个文件编译,变回:542.56DMIPS。
2.9DMIPS/M有点不可思议,官方数据才1027 DMIPS,2.14 DMIPS/MHz , 但我觉得我的数据应该还是可信的,估计官方数据是gcc编译,而某DK一般比gcc快,而且某DK的AC6(CLANG)又比老的5.x要快个百分之二三十。

ackyee 发表于 2022-2-10 19:35:11

stm32h750vb 系列 不可扩展SDRAM这个直接限制性能了,做RGB屏无法胜任   
STM32H750XBBGA封装可以拓展SDRAM 但是价格又高了

tomzbj 发表于 2022-2-10 19:37:52

ackyee 发表于 2022-2-10 19:35
stm32h750vb 系列 不可扩展SDRAM这个直接限制性能了,做RGB屏无法胜任   
STM32H750XBBGA封装可以拓 ...

100脚本来也不适合接sdram吧, 一下子把几十个脚用掉了...

wye11083 发表于 2022-2-10 20:01:11

LZ你用stm32cubemx配置时钟,有不兼容的软件就会直接报错让你修改。AHB原则上不动,flash延迟要加大一点,APB要根据情况去配,这点你用手算是算不出来的。

tomzbj 发表于 2022-2-10 20:12:02

wye11083 发表于 2022-2-10 20:01
LZ你用stm32cubemx配置时钟,有不兼容的软件就会直接报错让你修改。AHB原则上不动,flash延迟要加大一点,A ...

flash延迟加大也不会更快啊...

我不用cube和hal, 只用ll.

amigenius 发表于 2022-2-10 20:16:51

看一下Map文件, 看变量是否在0x20000000范围内, 这个是DTCM, 理论上能提供0等待的访问速度.
另外,上480M主频, Vcore电压要设置为VOS0, 并且FLASH LATENCY 可以设置为2等待周期.
AXI RAM的频率最高240M, 但好在总线宽度为64bit, 实际带宽也很高, 不过就是需要总线仲裁带来一些等待时间.

redroof 发表于 2022-2-10 20:23:07

你程序代码在flash里?堆栈呢?
是不是把堆栈也放到DTCM里会更好?
或者把代码也丢到ITCM里?

amigenius 发表于 2022-2-10 20:33:17

redroof 发表于 2022-2-10 20:23
你程序代码在flash里?堆栈呢?
是不是把堆栈也放到DTCM里会更好?
或者把代码也丢到ITCM里? ...

兄弟可能说到重点了, 堆栈需要放到DTCM.干脆把整个内存地址范围定义在DTCM内就好了.
至于代码, 开了Cache放不放ITCM影响不是很大, 就算放QPI Flash XIP也能有个八九成的性能,   放ITCM是那些非常非常频繁调用, 跳转很多的代码才有明显效果.

xuexikaifa 发表于 2022-2-10 20:58:51

卧槽。。。楼上几个居然都是VIP+++大神在讨论,我来沾点光。。。。。。。

tomzbj 发表于 2022-2-10 21:23:49

amigenius 发表于 2022-2-10 20:33
兄弟可能说到重点了, 堆栈需要放到DTCM.干脆把整个内存地址范围定义在DTCM内就好了.
至于代码, 开了Ca ...

楼上两位, 我把栈放DTCM了啊, 感觉没啥变化...
不知道是不是配置还有什么硬伤? 我的SystemInit是手写的
FLASH LATENCY这个, 开cache之后应该也没太大变化吧.

void SystemInit(void)    // called by startup script
{
    SCB_EnableICache();
    SCB_EnableDCache();
    LL_RCC_DeInit();
    LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
    LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
    while(!LL_PWR_IsActiveFlag_ACTVOS());

    LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
    LL_RCC_HSE_Enable();
    LL_RCC_HSE_EnableCSS();
    while(LL_RCC_HSE_IsReady() == 0);

    LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);

    LL_RCC_PLL1P_Enable();
    while(LL_RCC_PLL1P_IsEnabled() == 0);
    LL_RCC_PLL1Q_Enable();
    while(LL_RCC_PLL1Q_IsEnabled() == 0);
    LL_RCC_PLL1R_Enable();
    while(LL_RCC_PLL1R_IsEnabled() == 0);
    LL_RCC_PLL1FRACN_Enable();
    while(LL_RCC_PLL1FRACN_IsEnabled() == 0);

    LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
    LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);

    LL_RCC_PLL1_SetM(5);
    LL_RCC_PLL1_SetN(192);
    LL_RCC_PLL1_SetP(2);
    LL_RCC_PLL1_SetQ(20);
    LL_RCC_PLL1_SetR(2);

    LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
    LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2);
    LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
    LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
    LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_2);
    LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);

    LL_RCC_PLL1_Enable();
    while(LL_RCC_PLL1_IsReady() == 0);

    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
    while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUTS_PLL1);

    LL_SetSystemCoreClock(480000000UL);
    __enable_irq();
}

wye11083 发表于 2022-2-10 21:29:34

本帖最后由 wye11083 于 2022-2-10 21:33 编辑

tomzbj 发表于 2022-2-10 20:12
flash延迟加大也不会更快啊...

我不用cube和hal, 只用ll.

有cache啊。你以为cache是吃干饭的?

由于cache有命中延迟,所以理论上跳转多的代码cache性能反而有可能比不上itcm。

cubemx是用来生成初始化代码和配置的。stm32只有用cubemx才能完美初始化硬件。

还有,O2有可能比O3快。Os反而要比O2慢一小半,但是代码量可以省30%左右。

amigenius 发表于 2022-2-10 23:17:41

tomzbj 发表于 2022-2-10 21:23
楼上两位, 我把栈放DTCM了啊, 感觉没啥变化...
不知道是不是配置还有什么硬伤? 我的SystemInit是手写的
F ...

先看看Map文件, 看变量和堆栈是否落在 0x20000000~0x20020000范围内吧.
我没有用过LL库, 但您代码看起来没什么问题, 用的是25M晶振吧, M=5, N=192, P=2算出来的确实是480M的主频,就算受限于SRAM和Flash, 有cache的情况下, CPU主频高一倍, 也不可能停留在和200M一样的性能的.   我以前超频过玩一下, 550M比480M都要明显快不少, 虽然增幅不是线性.

qwe2231695 发表于 2022-2-10 23:49:52

可能要上mdk ac6编译器了 可以提升30%速度

minisystem 发表于 2022-2-11 09:10:37

tomzbj 发表于 2022-2-10 20:12
flash延迟加大也不会更快啊...

我不用cube和hal, 只用ll.

CUBE 也可以生产全LL代码

redroof 发表于 2022-2-11 09:21:17

本帖最后由 redroof 于 2022-2-11 09:31 编辑

amigenius 发表于 2022-2-10 23:17
先看看Map文件, 看变量和堆栈是否落在 0x20000000~0x20020000范围内吧.
我没有用过LL库, 但您代码看起来 ...

如果程序很频繁的让cache冲突,那么完全可能导致只受那个慢速SRAM限制,你增加cpu主频无效。当然这种情况很少见,造cpu cache的人会尽量避免这种情况。
dhrystone是专门的测试程序,里面一大堆各种不同的操作,感觉也不太可能是cache冲突。这个H7的DCache有4way,是常见的规格了,没那么差的运气。除非是写数据处理程序,专门跟cache作对。比如对这个cache,你只要按4k的间隔去循环访问一个大数组,4次以后就耗光了cache,以后每次cache都没有空间了,可以得到只由慢速ram决定的速度。

tomzbj 发表于 2022-2-11 11:39:10

amigenius 发表于 2022-2-10 23:17
先看看Map文件, 看变量和堆栈是否落在 0x20000000~0x20020000范围内吧.
我没有用过LL库, 但您代码看起来 ...


您好, 我把map文件贴上来了, 应该是全在DTCMRAM了
不过感觉速度还是没啥变化...
改O2也试了, 大概慢了个百分之几.

chunjiu 发表于 2022-2-11 11:51:33

关注,正准备抽空用它来做 8051 的第二代模拟器 :-)

saccapanna 发表于 2022-2-11 13:17:37

tomzbj 发表于 2022-2-10 20:12
flash延迟加大也不会更快啊...

我不用cube和hal, 只用ll.

我也是喜欢自己配,不过 CubeMX 用于IO分配,看看时钟树还有很方便的。另外,我记得 H750 的 APB 时钟最大是 128MHz,不会到记错没,你 480MHz 2分频可能是超了。

tomzbj 发表于 2022-2-11 13:36:29

chunjiu 发表于 2022-2-11 11:51
关注,正准备抽空用它来做 8051 的第二代模拟器 :-)

用它模拟8051是不是牛刀杀鸡了……
72M的f103足够了吧?

tomzbj 发表于 2022-2-11 13:39:20

saccapanna 发表于 2022-2-11 13:17
我也是喜欢自己配,不过 CubeMX 用于IO分配,看看时钟树还有很方便的。另外,我记得 H750 的 APB 时钟最 ...

apb是在ahb基础上再2分频吧,主频480, ahb 240, 那apb就是120了

chunjiu 发表于 2022-2-11 14:11:08

tomzbj 发表于 2022-2-11 13:36
用它模拟8051是不是牛刀杀鸡了……
72M的f103足够了吧?

之前研究过了,有性能陷阱,普通 Flash 存储器不适合跳转。

120M 的 STM32F207 只能实现 100K 左右主频的实时均速仿真。

若添加跟踪等功能,估计最大均速只能实现 10~20K 左右的主频。

amigenius 发表于 2022-2-11 14:35:24

tomzbj 发表于 2022-2-11 11:39
您好, 我把map文件贴上来了, 应该是全在DTCMRAM了
不过感觉速度还是没啥变化...
改O2也试了, 大概慢了个 ...

看Map是全在DTCM了,   开个定时器, 确认一下时钟是否真的480M

amigenius 发表于 2022-2-11 14:40:11

chunjiu 发表于 2022-2-11 14:11
之前研究过了,有性能陷阱,普通 Flash 存储器不适合跳转。

120M 的 STM32F207 只能实现 100K 左右主频 ...

STM32F系列都是靠高的Flash位宽, 加上Flash缓冲来提高取指效率, 非常频繁的跳转会损失不少性能, 但也不至于这么不堪, 您看72M的F103模拟FC的多欢快, 我估计您的模拟器架构可能要再找找原因.另外, 有ITCM和DTCM, 用来存放频繁跳转结构的程序非常合适, 那个是0等待, 100%发挥CPU效能.

chunjiu 发表于 2022-2-11 14:47:45

本帖最后由 chunjiu 于 2022-2-11 14:50 编辑

amigenius 发表于 2022-2-11 14:40
STM32F系列都是靠高的Flash位宽, 加上Flash缓冲来提高取指效率, 非常频繁的跳转会损失不少性能, 但也不至 ...

6502 和 8051 不是同样的架构,所以我开始的失误就是忽略了它们之间的差异。

当然,之前对 8051 不熟悉也是原因之一,有点想得过于简单化了。

PS:

现在就是看中 750 的 ITCM 够大 ...

chunjiu 发表于 2022-2-11 14:53:40

本帖最后由 chunjiu 于 2022-2-11 15:07 编辑

十年前做过一个 6502 的指令核,跑的很完美,不过代码现在还不知是否能找到。

也就是因为做过 6502 的模拟器,所以才对 8051 产生了深深的误解。 {:lol:}

saccapanna 发表于 2022-2-11 15:31:25

tomzbj 发表于 2022-2-11 13:39
apb是在ahb基础上再2分频吧,主频480, ahb 240, 那apb就是120了

记错了,刚才查了一下,APB 是 200MHz

amigenius 发表于 2022-2-11 15:47:34

本帖最后由 amigenius 于 2022-2-11 15:48 编辑

chunjiu 发表于 2022-2-11 14:47
6502 和 8051 不是同样的架构,所以我开始的失误就是忽略了它们之间的差异。

当然,之前对 8051 不熟悉 ...

我记得我在99年时, 那时候还在读高中没钱, 在广州大沙头买了台古董 486DX 笔记本,拿回学校, 逃晚修在宿舍学习51, 那时候486DX, 66M的主频跑51的软件模拟, 速度也很快啊.

amigenius 发表于 2022-2-11 15:49:59

chunjiu 发表于 2022-2-11 14:53
十年前做过一个 6502 的指令核,跑的很完美,不过代码现在还不知是否能找到。

也就是因为做过 6502 的模拟 ...

我很奇怪, 您非要跑个8051模拟器干嘛? 哈哈

chunjiu 发表于 2022-2-11 15:58:53

amigenius 发表于 2022-2-11 15:47
我记得我在99年时, 那时候还在读高中没钱, 在广州大沙头买了台古董 486DX 笔记本,拿回学校, 逃晚修在宿 ...

x86 当然很牛逼啊,之前在 PC 上调试刚写出的模拟器草稿代码时,没做优化都跑出了 18MHz 的 1T 成绩,相当于初代 8051 的 18*12 = 216MHz 主频 {:lol:}

做 8051 模拟器还是想实现一个好用的 debuger,这样在使用国产 MCU 的时候就不会感觉到痛苦了。

目前手上的事情太多,要消化一大部分之后才能开始做这个新一代架构的 8051 模拟器。初代架构因考虑不周就放弃了,达不到理想的实用效果做下去就没意义。

amigenius 发表于 2022-2-11 16:10:25

chunjiu 发表于 2022-2-11 15:58
x86 当然很牛逼啊,之前在 PC 上调试刚写出的模拟器草稿代码时,没做优化都跑出了 18MHz 的 1T 成绩,相 ...

486DX呢,只有66M, 刨除MMU, 光说性能, 407都能吊打它.
您为了用国产MCU时Debug得欢快而搞个模拟器,这个动机很屌啊. 一来51能跑多复杂的程序, 用不用Debug无所谓了, 挂个串口输出一下就好. 二来您软件模拟器不见得没有bug, 就算无bug, 软件模拟也不能100%还原不同厂家所有内部时序,各种隐藏 bug啊. 三来您真要尽情仿真并且尽情调试, 何不用FPGA写软核呢

chunjiu 发表于 2022-2-11 16:21:17

amigenius 发表于 2022-2-11 16:10
486DX呢,只有66M, 刨除MMU, 光说性能, 407都能吊打它.
您为了用国产MCU时Debug得欢快而搞个模拟器,   ...

去年在 51 子栏目中讨论过了,纯粹就是为了方便自己的产品开发 {:lol:}

自己设计的 Debuger 要携带方便、仿真便利,调试场景灵活,用户可动态编辑执行中的指令,

否则市场上有那么多的老产品可用,还搞它干啥? {:lol:}

tomzbj 发表于 2022-2-11 16:45:10

chunjiu 发表于 2022-2-11 14:11
之前研究过了,有性能陷阱,普通 Flash 存储器不适合跳转。

120M 的 STM32F207 只能实现 100K 左右主频 ...

不是吧? 那就全部读到RAM再执行? 一般51也没几k ram吧.

或者用全部零等待的GD32F30x? 这东西其实是把flash全部镜像到ram里了, 比如GD32FFPRTGU6, 168M主频, 可以稳定超频到280M.

tomzbj 发表于 2022-2-11 17:03:32

amigenius 发表于 2022-2-11 14:35
看Map是全在DTCM了,   开个定时器, 确认一下时钟是否真的480M

直接让PC9当MCO2, 输出SYSCLK 10分频, 用示波器看是48M, 主频480M应该没问题了.

chunjiu 发表于 2022-2-11 17:07:20

tomzbj 发表于 2022-2-11 16:45
不是吧? 那就全部读到RAM再执行? 一般51也没几k ram吧.

或者用全部零等待的GD32F30x? 这东西其实是把fla ...

因为 51 指令集将普通的 RAM 当作寄存器使用,其寻址方式中有通过 RAM 的内容做索引寄存器,然后还要运算引用,

这就相当于它有 256 个间接寻址的寄存器,其储存内容可当作内存的地址索引 ... 在当年此技术是相当的变态(犀利)!

这就是 arm crotex-m 的软肋:不是线性寻址,而且还绕来绕去走了几个弯子,导致 Flash 长数据 cache 无效,指令执行效率低下。

tomzbj 发表于 2022-2-11 17:17:13

chunjiu 发表于 2022-2-11 17:07
因为 51 指令集将普通的 RAM 当作寄存器使用,其寻址方式中有通过 RAM 的内容做索引寄存器,然后还要运算 ...

这和6502的零页不是差不多么...

chunjiu 发表于 2022-2-11 17:35:25

tomzbj 发表于 2022-2-11 17:17
这和6502的零页不是差不多么...

比 6502 零页还多一级引用,而且是两个零页地址的内容进行互相操作运算(多工),不像 6502 仅仅是某个寄存器和零页之间的单工操作。

redroof 发表于 2022-2-11 20:22:27

chunjiu 发表于 2022-2-11 17:07
因为 51 指令集将普通的 RAM 当作寄存器使用,其寻址方式中有通过 RAM 的内容做索引寄存器,然后还要运算 ...

我不记得51汇编有这个功能啊。
请举例。
在我记忆里,只有寄存器R0和R1可以当索引,普通内存不能

redroof 发表于 2022-2-11 20:25:26

chunjiu 发表于 2022-2-11 17:35
比 6502 零页还多一级引用,而且是两个零页地址的内容进行互相操作运算(多工),不像 6502 仅仅是某个寄 ...

我记得两个内部RAM也不能直接做运算啊,所有运算必须有一个操作数是ACC

tomzbj 发表于 2022-2-11 20:42:42

继续努力, 换回-O3, gcc从4.9.3换成了10.2.1, 现在跑分提高到了599DMIPS, 1.25DMIPS/MHz
和标称的1027DMIPS,2.14DMIPS/MHz还是差距太大...

chunjiu 发表于 2022-2-11 20:45:22

redroof 发表于 2022-2-11 20:25
我记得两个内部RAM也不能直接做运算啊,所有运算必须有一个操作数是ACC

不好意思哈... 记忆有误,是数据搬移指令 :

85        3        MOV        direct, direct
86        2        MOV        direct, @R0

chunjiu 发表于 2022-2-11 20:48:45

本帖最后由 chunjiu 于 2022-2-11 20:51 编辑

redroof 发表于 2022-2-11 20:22
我不记得51汇编有这个功能啊。
请举例。
在我记忆里,只有寄存器R0和R1可以当索引,普通内存不能 ...

R0 和 R1 其实是类似 6502 的零页 RAM,不是真的寄存器。

R0 和 R7 都是假寄存器,而且映射到 RAM 中四个不同的组:

分组是第一层引用,Rx 是第二层引用,@R0/1 是第三层引用。

tomzbj 发表于 2022-2-11 20:57:50

再试AHB 1分频, 从240开始往上超, 到350M还能运行, 可以跑到889DMIPS, 400M是怎么也不行了
这个状态肯定是不对的....

tomzbj 发表于 2022-2-11 22:42:51

继续努力, 把dhrystone的几个函数放进DTCM/ITCM, 具体方法:

1. 在链接脚本里加一段
    _siRAMFUNC = LOADADDR(.RAMFUNC);
    .RAMFUNC :
    {
      . = ALIGN(4);
      _sRAMFUNC = .;
      *(.RAMFUNC)         
      *(.RAMFUNC*)         
      . = ALIGN(4);
      _eRAMFUNC = .;      
    } >DTCMRAM AT> FLASH

2. 在程序里初始化之后, 进dhrystone之前加一段:
   extern char _siRAMFUNC;
    extern char _sRAMFUNC;
    extern char _eRAMFUNC;
    char* src = &_siRAMFUNC;
    char* dst = &_sRAMFUNC;
    char* dst_end = &_eRAMFUNC;
    printf("%08lX%08lX%08lX\n", (unsigned long)src, (unsigned long)dst,
      (unsigned long)dst_end);
    while(dst < dst_end) {
      *dst = *src;
      dst++;
      src++;
    }

3. 在dhrystone里给各个函数原型加上__attribute__((section(".RAMFUNC")))

然后查看map文件, 确实这些函数都在DTCM了,也成功运行了, 但是速度比之前还慢了40%左右.
再把DTCM换成ITCM, 一样, 也是慢了40%左右.

redroof 发表于 2022-2-12 08:45:52

chunjiu 发表于 2022-2-11 20:48
R0 和 R1 其实是类似 6502 的零页 RAM,不是真的寄存器。

R0 和 R7 都是假寄存器,而且映射到 RAM 中四 ...

不管它实际是RAM还是寄存器,反正就只有当前寄存器组的R0和R1能当指针。
物理结构上我也认为对普通12周期的51来说,它可以是普通RAM,不需要是寄存器。
你看那些号称单周期的51哪些指令可以单周期,哪些要多个周期,就知道了。用R0间接访问肯定是比较慢的一类。因为它就是个普通RAM,内部隐含了先读它的值,再拿去做问接寻指的过程。
这对你仿真没什么问题啊,你知道它是这样的,也同样的做就是了呗。ARM才是真的任何寄存器都能做任何用途呢,而且都是最快的速度,不是老51那样强行用12周期拖慢所有的操作。
ARM用任何内存做间接寻指都是三个指令:装指针自己的地址,读入指针,拿指针读写数据。比标准51快的多。

redroof 发表于 2022-2-12 08:49:29

tomzbj 发表于 2022-2-11 22:42
继续努力, 把dhrystone的几个函数放进DTCM/ITCM, 具体方法:

1. 在链接脚本里加一段


代码必须在itcm,数据在dtcm,不能反,反了没用。把代码放在DTCM里肯定会慢,因为跟数据冲突了。

redroof 发表于 2022-2-12 08:58:34

chunjiu 发表于 2022-2-11 20:48
R0 和 R1 其实是类似 6502 的零页 RAM,不是真的寄存器。

R0 和 R7 都是假寄存器,而且映射到 RAM 中四 ...

你说的这个问题实际就是几十年前的RISC和CISC之争,答案早已明确,RISC除了代码密度以外,别的方面都胜岀。所以从那以后新岀的cpu都是RISC了。
CISC执行一条带双地址的MOV,并不比RISC执行两条单独的读和写合起来的速度快。双地址mov本质上执行方法也是一样的:先把源地址的内容读岀来,放到临时位置,再对目标地址发一个写。因为硬件上没有别的实现方法。

tomzbj 发表于 2022-2-12 10:36:46

redroof 发表于 2022-2-12 08:49
代码必须在itcm,数据在dtcm,不能反,反了没用。把代码放在DTCM里肯定会慢,因为跟数据冲突了。 ...

我感觉没区别, dhrystone的核心部分代码没多少,填不满cache吧...

redroof 发表于 2022-2-12 10:52:16

本帖最后由 redroof 于 2022-2-12 10:55 编辑

tomzbj 发表于 2022-2-12 10:36
我感觉没区别, dhrystone的核心部分代码没多少,填不满cache吧...

谁知道呢~
想不通为什么这个H7这么麻烦,我的IMX6就在SDRAM里运行也能直接达到足够好的dhrystone性能啊,根本没想着怎么去手工分配内存来优化。。。
H7内置的半速SRAM至少比我的片外SDRAM要快好多倍啊,CortexM7和A7核心性能应该差不多的。
或者是因为我的A7的Cache比你大得多,它有32K+32K的L1,还有个128K的L2{:titter:}
但我的L2 Cache有2个周期延时,其实还不如你的半速SRAM

chunjiu 发表于 2022-2-12 11:07:41

redroof 发表于 2022-2-12 08:58
你说的这个问题实际就是几十年前的RISC和CISC之争,答案早已明确,RISC除了代码密度以外,别的方面都胜岀 ...

在硬件上,实现寻址方式比较简单,不出意外的话就是增加逻辑门的密度来加速。

但模拟器用软件实现就涉及到大量的 if 跳转,这是 arm 的 m 核硬伤。

因 flash 没那么快,会导致指令线不停的刷新重置,这个折扣很厉害。

所以我才看中 750 的 TCM 够大,好折腾。

redroof 发表于 2022-2-12 11:44:17

chunjiu 发表于 2022-2-12 11:07
在硬件上,实现寻址方式比较简单,不出意外的话就是增加逻辑门的密度来加速。

但模拟器用软件实现就涉及 ...

这不是ARM结构的问题,是Flash本身就跑不快。你用任何一个从Flash里面运行代码的高速CPU来模拟,都是一样的问题。
ARM结构已经是性能和指令复杂度都很理想的了。比老式CPU结构都好得多。
其实任何一种现代的RISC CPU基本上在相同复杂度的档次下性能都差不多,比如RISC V,或者MIPS,大家都做到了常规指令每个时钟执行一条。谁也没有更好的方法。继续堆性能只能用很复杂的方法了。

chunjiu 发表于 2022-2-12 12:11:49

redroof 发表于 2022-2-12 11:44
这不是ARM结构的问题,是Flash本身就跑不快。你用任何一个从Flash里面运行代码的高速CPU来模拟,都是一样 ...

跑 6502 就没问题,才固定三个 8 bit 寄存器,加上堆栈指针和隐含的零页索引寄存器,编译出来的代码几乎不需要从 RAM 交换变量数据。

因为 6502 的寻址方式简单可预测,实现它的指令集也很简单,所以用 arm 的 mcu 实现起来没多少跳转代码,在 Flash 中执行就没太多的效率折扣。

我之前也就是因为这个原因才被误导了,做出来之后才发现 8051 和 6502 的结构差异性太大了。

redroof 发表于 2022-2-12 13:08:41

chunjiu 发表于 2022-2-12 12:11
跑 6502 就没问题,才固定三个 8 bit 寄存器,加上堆栈指针和隐含的零页索引寄存器,编译出来的代码几乎 ...

这完全取决于你的做法。
如果51的寄存器组你都当普通RAM来对付,那么它也不比6502复杂啊,特殊寄存器只有累加器,状态寄存器和堆栈指针,还有乘除用的B寄存器,也是4个而已。
主要是6502的寄存器都不在主内存里,内存就是内存,而51的累加器这些都在主内存的sfr区有地址,用户可以从这里间接操作寄存器。所以所有的操作ram的地方都得检查这些特殊的东西。

tomzbj 发表于 2022-2-12 14:06:50

redroof 发表于 2022-2-12 10:52
谁知道呢~
想不通为什么这个H7这么麻烦,我的IMX6就在SDRAM里运行也能直接达到足够好的dhrystone性能啊 ...

我也想不明白, 但是既然datasheet第一页写了480MHz, 2.14DMIPS/MHz,1027DMIPS, 那说明它肯定是实际能跑出这个性能的

f103还算老实, 72M, 零等待状态下1.25DMIPS/MHz,   总之到不了90DMIPS

redroof 发表于 2022-2-12 14:17:04

tomzbj 发表于 2022-2-12 14:06
我也想不明白, 但是既然datasheet第一页写了480MHz, 2.14DMIPS/MHz,1027DMIPS, 那说明它肯定是实际能跑 ...

103只告诉你零等待状态的性能啊{:titter:}
实际高频的时候无法零等待,也没骗你。

amigenius 发表于 2022-2-12 15:17:22

tomzbj 发表于 2022-2-12 14:06
我也想不明白, 但是既然datasheet第一页写了480MHz, 2.14DMIPS/MHz,1027DMIPS, 那说明它肯定是实际能跑 ...

方便把代码发上来一下吗? 我找时间用MDK的CLANG编译一下试试

tomzbj 发表于 2022-2-12 17:39:41

amigenius 发表于 2022-2-12 15:17
方便把代码发上来一下吗? 我找时间用MDK的CLANG编译一下试试

好啊
麻烦你啦

huangqi412 发表于 2022-2-14 13:55:42

官方开发板不知道是否有性能测试相关例程。

amigenius 发表于 2022-2-15 00:05:48

本帖最后由 amigenius 于 2022-2-15 00:14 编辑

qwe2231695 发表于 2022-2-15 03:56:23

楼上果然是高手,这样的问题都排得出来,没想到还是cache优化问题。

Pjm2008 发表于 2022-2-15 07:18:25

NBA,思路不是一般的广,大部分人都放弃。

tomzbj 发表于 2022-2-15 07:45:39

amigenius 发表于 2022-2-14 23:59
刚才抽空测试了一下,Y版本的750,最高400M, 代码放内部Flash,变量默认全放DTCM,某DK5.3学习版Licence! ...

太赞了,原来是这样!我晚上也试试。
官方数据估计是用gcc4之类老版本测的,我之前也发现用gcc10会再快一点。

redroof 发表于 2022-2-15 08:50:02

amigenius 发表于 2022-2-14 23:59
刚才抽空测试了一下,Y版本的750,最高400M, 代码放内部Flash,变量默认全放DTCM,某DK5.3学习版Licence! ...

cache性能跟代码的大小应该没什么关系啊,多岀来的代码只要不执行就没事。问题应该是cache冲突。
4路16k的cache,如果有5个或更多的地址相差4k倍数的代码,那么就装不进了。
所有代码放一个文件当然是最好效果,从任意地址起的连续16k都能装进cache。
不同的文件,如果你可以排列各个文件的link顺序,也可以试一下改变顺序。
或者故意给这三个文件中的某个文件头部加1-3K的无用代码(常量数组应该也行),很可能这个文件的地址就不跟另一个文件争抢cache了。速度就快起来了

amigenius 发表于 2022-2-15 08:51:36

tomzbj 发表于 2022-2-15 07:45
太赞了,原来是这样!我晚上也试试。
官方数据估计是用gcc4之类老版本测的,我之前也发现用gcc10会再快一 ...

有空再试一下itcm,v版本,再超频,看看还能有多少提升,哈哈

flash3g 发表于 2022-2-15 12:38:29

{:biggrin:}{:biggrin:}大佬们很强。。

amigenius 发表于 2022-2-15 12:48:40

redroof 发表于 2022-2-15 08:50
cache性能跟代码的大小应该没什么关系啊,多岀来的代码只要不执行就没事。问题应该是cache冲突。
4路16k ...

刚刚分别看了两种情况下编译出来的Map文件,分三个文件的,里面的函数在Flash分了几大段地址,每段地址偏移了10K左右,加上我项目内本身有些定时中断、串口中断,估计cache miss多了。而放一个文件内的,各函数地址都连续,而且Ofast后,有些自动内联了,cache能完全命中。

tomzbj 发表于 2022-2-15 21:59:47

本帖最后由 tomzbj 于 2022-2-15 22:02 编辑

amigenius 发表于 2022-2-14 23:59
刚才抽空测试了一下,Y版本的750,最高400M, 代码放内部Flash,变量默认全放DTCM,某DK5.3学习版Licence! ...

晚上我也合到一个文件里, 折腾半天, 只做到了0.74ms, 769DMIPS, 1.60DMIPS/MHz,编译器是gcc10

但是降频到240M, AHB 1分频的话居然也能做到0.75ms, 759DMIPS,这样就有3.16DMIPS/MHz了...这是什么鬼现象... 感觉还是不太对劲.

你有空的话也试试降到240M, AHB 1分频, 看能跑到什么分数?

amigenius 发表于 2022-2-15 23:27:25

tomzbj 发表于 2022-2-15 21:59
晚上我也合到一个文件里, 折腾半天, 只做到了0.74ms, 769DMIPS, 1.60DMIPS/MHz,编译器是gcc10

但是降 ...
(引用自67楼)

昨晚折腾的时候试过,ahb1分频和2毫无区别,,无论是否合并文件
页: [1]
查看完整版本: 再试STM32H750VB的dhrystone性能