OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3031|回复: 11

STR指令到底是单周期还是多周期的???

[复制链接]

8

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
439
金钱
439
注册时间
2018-12-21
在线时间
126 小时
发表于 2020-3-6 22:23:56 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 0x00000000 于 2020-3-19 21:23 编辑

根据ARM的技术手册,
ARM® Cortex®-M3 Processor Revision: r2p1 Technical Reference Manual
;这是文件名包含版本,这里提到几个机制的原文如下:
STR Rx,[Ry,#imm] is always one cycle. This is because the address generation is performed in the
initial cycle
, and the data store is performed at the same time as the next instruction is executing. If
the store is to the write buffer, and the write buffer is
full or not enabled
, the next instruction is
delayed until the store can complete. If the store is not to the write buffer, for example to the Code
segment, and that transaction stalls, the impact on timing is only felt if another load or store operation
is executed before completion.
所以可以知道,当写缓存有的情况下而且没满,写入操作理论上就应该是单周期指令,结果使用Keil进行仿真,内核启动后第一条写指令就消耗了2个周期???
执行前:
091227ysct365c4es8b19e.jpg

执行后:

091227etl21p3l8nnx71fn.jpg



What the FUCK it is?
说好的单周期变成2个周期了?到底是那里的问题呢?
补充说明:上一条指令被翻译成:MOV R1,#0x20000000的机器码,不是LDR R1,[R15,#Offset]这种文字池加载立即数形式,所以不是前一条指令和后面STR发生Write after read冲突引起的流水线阻塞引起的延迟。



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2015-5-7
在线时间
20 小时
发表于 2020-3-18 14:43:00 | 显示全部楼层
请教一下,楼主图片中States的变化就是指执行一条指令所用的时钟周期么?底下的Sec的变化就是指,执行这条指令所用的时间么?
回复

使用道具 举报

8

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
439
金钱
439
注册时间
2018-12-21
在线时间
126 小时
 楼主| 发表于 2020-3-18 22:24:52 | 显示全部楼层
RYOMARYOMA 发表于 2020-3-18 14:43
请教一下,楼主图片中States的变化就是指执行一条指令所用的时钟周期么?底下的Sec的变化就是指,执行这条 ...

是的,不过时钟周期是具有平均意义的,不是说这条指令就正好一个周期,实际上一条所谓的单周期指令都是要3个时钟周期,但是每个时钟周期同时执行3条指令,所以平均下来一时钟周期一指令/。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2020-3-19 01:00:06 | 显示全部楼层
其他指令,这么看,是1个周期么?比如加操作。
回复

使用道具 举报

8

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
439
金钱
439
注册时间
2018-12-21
在线时间
126 小时
 楼主| 发表于 2020-3-19 11:18:17 | 显示全部楼层
正点原子 发表于 2020-3-19 01:00
其他指令,这么看,是1个周期么?比如加操作。

是的。
回复

使用道具 举报

8

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
439
金钱
439
注册时间
2018-12-21
在线时间
126 小时
 楼主| 发表于 2020-3-19 11:30:31 | 显示全部楼层
正点原子 发表于 2020-3-19 01:00
其他指令,这么看,是1个周期么?比如加操作。

我傻了,我太相信软件仿真了,这个工程写完以后软件仿真了一下行为没啥问题,直接烧录测试,结果直接进了Hardfault。
原来是某些寄存器不支持字节访问,虽然RM0008中说是可以的,包括软件仿真没毛病。但是实际测试就不行。
刚才试了试在线调试,发现STR变成单周期了。而且不仅是访问内存,连修改寄存器都是单周期的。根据STM32的Program manual描述,Write buff只是适用于写内存的时候加速STR指令,没有说写寄存器也是这样,这是原文:Enable write buffer use: stores to memory is competed before next instruction,在SCB_ACTLR寄存器的第一位控制默认开启。
而且,不仅是STR,连STRH,STRB之类的指令周期都是1周期,这是ARM 的内核描述文件中没说过的。
回复

使用道具 举报

8

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
439
金钱
439
注册时间
2018-12-21
在线时间
126 小时
 楼主| 发表于 2020-3-19 11:34:59 | 显示全部楼层
反正不管怎么样,现在我的工程能跑了。以后也可以放心地把带有立即数偏移的STR,STRH,STRB当成单周期的对待了。这样优化的时候非常方便,毕竟频繁读写内存的程序,经常容易发生Write after read,或者write after write这种流水线冲突。
回复

使用道具 举报

6

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2015-5-7
在线时间
20 小时
发表于 2020-3-19 15:09:30 | 显示全部楼层
0x00000000 发表于 2020-3-18 22:24
是的,不过时钟周期是具有平均意义的,不是说这条指令就正好一个周期,实际上一条所谓的单周期指令都是要 ...

[实际上一条所谓的单周期指令都是要 3个时钟周期],,,这里是指取址、译码和执行么?如果是的话,我理解的,cpu执行一条指令的时候,先从flash里边取址,这个时间花费的比较长吧?不止1个时钟周期吧?
回复

使用道具 举报

6

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2015-5-7
在线时间
20 小时
发表于 2020-3-19 15:20:48 | 显示全部楼层
再请教一下,比如我用汇编循环跑一段代码N次,这段汇编代码一共有X条单周期指令。跑N次所用时间测量出来为T,那么可以这样来计算cpu的时钟t么? t = (T/N) /X
回复

使用道具 举报

8

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
439
金钱
439
注册时间
2018-12-21
在线时间
126 小时
 楼主| 发表于 2020-3-19 18:57:01 | 显示全部楼层
RYOMARYOMA 发表于 2020-3-19 15:09
[实际上一条所谓的单周期指令都是要 3个时钟周期],,,这里是指取址、译码和执行么?如果是的话,我理解的 ...

对于具有0等待的FLASH来说可以这样认为,但是,STM32的FLASH比较烂,72MHz以上的主频必须要设置2个等待周期,所以执行速度当然慢了,被取指令过程拖后腿。
另外Cortex-M3好像是每次取32bit内容,当取出2条16bit的指令时,取指会延后一个周期。Thumb-2指令集是支持指令压缩的,简单的指令是16bit。
而GD32比较厉害,在108MHz下还能以0等待方式工作,所以同频下GD32性能优于STM32.
回复

使用道具 举报

8

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
439
金钱
439
注册时间
2018-12-21
在线时间
126 小时
 楼主| 发表于 2020-3-19 18:59:29 | 显示全部楼层
RYOMARYOMA 发表于 2020-3-19 15:20
再请教一下,比如我用汇编循环跑一段代码N次,这段汇编代码一共有X条单周期指令。跑N次所用时间测量出来为T ...

当X值非常大时,可以估计的差不多。
别忘了跳转指令要消耗越3个周期,因造成流水线冲洗重装。所以你的循环体应该足够长使得分支指令的影响可以忽略不记。
回复

使用道具 举报

6

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2015-5-7
在线时间
20 小时
发表于 2020-3-20 09:52:52 | 显示全部楼层
0x00000000 发表于 2020-3-19 18:59
当X值非常大时,可以估计的差不多。
别忘了跳转指令要消耗越3个周期,因造成流水线冲洗重装。所以你的循 ...

1. 这里应该是当N的值非常大时,可以估计的差不多吧?
2. 我用的BLT跳转的,调试时,查看States的值,也只是变化了1呢,没有测出要消耗3个周期呢?
3. 如果不是0等待的FLASH,即使N特别大,用上述公式算出来的值,应该也会比实际的cpu频率小吧,因为flash取址会拖后腿,不知道我这样理解对不对呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-23 02:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表