guolun 发表于 2015-6-25 09:48:10

编写STM32程序,uint8_t、uint16_t数据类型是否影响原子操作?

我从8位机的时代走过来,思维还是这样的:uint8_t够用,就不用uint16_t,uint16_t够用的,就不用uint32_t.
但32位系统中,用uint8_t时,编译出来的汇编指令数增加了。但uint16_t好像跟uint32_t一样的指令数。
除了指令数,临界区原子操作也有影响。比如,我中断里面对int32_t类型的数据加1,中断外面对这个数据减1,单周期操作完成,可以不用临界区保护。如果用uint8_t,会有问题。
不知道上面对否?各位可否共同探讨一下?

xhcyfc 发表于 2015-6-25 10:13:50

要改变观念了,以后32位单片机越来越强,编程也越来越PC化,所以变量定义最好直接用32位或者16位,这样以后程序再怎么升级,基本不会有溢出问题

desertsailor 发表于 2015-6-25 10:14:43

我也试过,同样的延时函数,将变量定义为16位数据比8位数据的执行起来更快

ruanxianwu 发表于 2015-6-25 10:16:28

你声明一个变量的时候,51奇葩可能将它放在的了内部的128字节的寄存器,所有有在内部的128字节的寄存器有单条自增和自减。
但是在其他CPU上面,基本都是将他放在内存上,都是读,修改,写回。不管是什么类型,基本不会有单周期可以完成的

styleno1 发表于 2015-6-25 10:26:01

认同楼主的用法,当然优先按需求分配空间。

modbus 发表于 2015-6-25 10:30:08

楼主理解有误,STM32的内存int32类型的加1减1也不是原子操作,单周期不可能完成

guolun 发表于 2015-6-25 10:32:10

modbus 发表于 2015-6-25 10:30
楼主理解有误,STM32的内存int32类型的加1减1也不是原子操作,单周期不可能完成 ...

我要重新看看《Cortex M3权威指南》了。

modbus 发表于 2015-6-25 10:42:42

如果用STM32去处理8位数据,效率还不如8位机,如果内存不是很紧张的话尽量别用8位数据类型。

guolun 发表于 2015-6-25 10:45:24

modbus 发表于 2015-6-25 10:42
如果用STM32去处理8位数据,效率还不如8位机,如果内存不是很紧张的话尽量别用8位数据类型。 ...

请问:用16位与32位,效率上有多大区别?我没做更多的测试,只测试过少量的几个函数。我的测试结果是没有区别。

guolun 发表于 2015-6-25 10:50:16

ruanxianwu 发表于 2015-6-25 10:16
你声明一个变量的时候,51奇葩可能将它放在的了内部的128字节的寄存器,所有有在内部的128字节的寄存器有单 ...

那样的话,uint8_t只影响执行效率,要原子操作,还是需要临界区保护措施。比如互斥体技术。你的意见呢?

styleno1 发表于 2015-6-25 10:50:54

modbus 发表于 2015-6-25 10:42
如果用STM32去处理8位数据,效率还不如8位机,如果内存不是很紧张的话尽量别用8位数据类型。 ...

还请补充依据或出处?

ruanxianwu 发表于 2015-6-25 11:02:46

guolun 发表于 2015-6-25 10:50
那样的话,uint8_t只影响执行效率,要原子操作,还是需要临界区保护措施。比如互斥体技术。你的意见呢? ...

嗯,uint8_t不一定比uint32_t快的。跟机器处理位数匹配的是效率最高的,STM32是32位的,所以uint32_t至少会比uint8_t快
互斥都是通过开中断和关中断来实现的。

guolun 发表于 2015-6-25 12:00:01

ruanxianwu 发表于 2015-6-25 11:02
嗯,uint8_t不一定比uint32_t快的。跟机器处理位数匹配的是效率最高的,STM32是32位的,所以uint32_t至少 ...

你说,互斥访问都用开关中断的方法。我重新查阅了《cortex m3 权威指南》(中文版),在95页,有LDREX/STREX 互斥访问的指令对。我的理解是:用汇编不需要开关中断就可以实现的。用C怎么实现?不懂了。

823032003 发表于 2015-6-25 12:03:35

modbus 发表于 2015-6-25 10:30
楼主理解有误,STM32的内存int32类型的加1减1也不是原子操作,单周期不可能完成 ...

请问 32bit的单片机 ,加1减1也不是原子操作?

谢谢

chen_ym 发表于 2015-6-25 12:20:12

弱弱的问一句,什么叫原子操作?

ruanxianwu 发表于 2015-6-25 12:26:31

guolun 发表于 2015-6-25 12:00
你说,互斥访问都用开关中断的方法。我重新查阅了《cortex m3 权威指南》(中文版),在95页,有LDREX/ST ...

说了,你定义一个变量的时候,是放在内存中的,和51不同的。51是可以放在内部的128(还是256)的内存中的
内存是独立于CPU的,STM32和51是不同的,STM32的CPU里面只有十来个寄存器。
一般情况下(特殊情况register暂不考虑),比如 i++,当你需要最这个变量进行操作,需要把i从内存中读回CPU的R0中,然后才是INC R0,然后再把R0写回到内存中。
所以不管你i是什么类型的。都是需要三个步骤才能完成一次操作的。假如你要保证他的原子性,i++之前关闭中断,然后再打开。这样就不会有其他中断抢占他了

peterlzj 发表于 2015-6-25 12:47:24

涨姿势了{:smile:}

823032003 发表于 2015-7-6 21:14:06

ruanxianwu 发表于 2015-6-25 12:26
说了,你定义一个变量的时候,是放在内存中的,和51不同的。51是可以放在内部的128(还是256)的内存中的 ...

请问读 修改 写 这种i++ 的方式会影响“原子操作”吗?

这么感觉不会呢


--------【此处被打断,不受影响】
修改
--------【此处被打断,不受影响】



谢谢

823032003 发表于 2015-7-6 21:15:07

ruanxianwu 发表于 2015-6-25 12:26
说了,你定义一个变量的时候,是放在内存中的,和51不同的。51是可以放在内部的128(还是256)的内存中的 ...

请问读 修改 写 这种i++ 的方式会影响“原子操作”吗?

这么感觉不会呢


--------【此处被打断,不受影响】
修改
--------【此处被打断,不受影响】



谢谢

semonpic 发表于 2015-7-6 21:30:28

确实和有可能如楼主所说。32CPU 在处理 8bit ++ 时,在汇编的时候可能会做数据转换,影响性能

wq_601840968 发表于 2019-7-24 09:26:07

ruanxianwu 发表于 2015-6-25 12:26
说了,你定义一个变量的时候,是放在内存中的,和51不同的。51是可以放在内部的128(还是256)的内存中的 ...

是三个步骤完成++操作,但是这三条指令之间被中断打断,并不会影响最后一条指令向内存中写入的值吧,所以我认为这个地方并不需要关中断进行保护,不知道理解的有没有问题?

wq_601840968 发表于 2019-7-24 09:26:27

823032003 发表于 2015-7-6 21:15
请问读 修改 写 这种i++ 的方式会影响“原子操作”吗?

这么感觉不会呢


我也觉得没问题

一夕nandy 发表于 2019-7-24 09:45:38

STM32 用uint_8编译出来的代码量比用 uint16_t/32_t 的大

modbus 发表于 2019-7-24 10:47:55

wq_601840968 发表于 2019-7-24 09:26
我也觉得没问题

如果中断外减1条件和中断同时有效时,原子操作可保证这个变量值不变,而非原子操作的话这个变量值可能不变,也可能减1,而这种差异对程序有没有影响则要看具体程序要求了

Lyndon.Sun 发表于 2019-7-25 21:21:52

涨姿势了!

lcmdw 发表于 2019-7-25 22:17:00

学习了   

flash3g 发表于 2023-8-14 16:53:04

823032003 发表于 2015-7-6 21:15
请问读 修改 写 这种i++ 的方式会影响“原子操作”吗?

这么感觉不会呢
(引用自19楼)


--------【此处被打断,不受影响】   !!别的进程修改这个变量
修改
--------【此处被打断,不受影响】   !!别的进程修改这个变量



最后写入就覆盖了中间的操作
页: [1]
查看完整版本: 编写STM32程序,uint8_t、uint16_t数据类型是否影响原子操作?