开发实时性较高的程序

黑娃 2017-03-03 01:00:03
我需要开发一个对实时性要求较高的程序,要UI,TCP,甚至是一些图像算法,实时性最好能控制在10ms以内,不用计较到底要多快,总之就是在十几ms的级别。我对这方面的技术比较欠缺,不知道有什么办法能够提高实时性,以前的桌面程序我都是用WPF在做,很难满足这么高的实时性,然后网上看了下,有个叫intervalZero的公司做的RTX能够将windows变成一个硬实时操作系统,但是没有免费的,暂不考虑。如果用专门的vxworks这些就更贵了,更不用考虑。现在我纠结的是,还有没其他解决方案,比如,如果我用QT+ubantu、centOs等普通linux来开发,会不会比windows+.net好一点,或者在操作系统之上的技术层面,有没有对实时性有提升的办法,毕竟我对实时性的要求还是在毫秒级,而且还有UI需求,还是希望能够在开发工具方便一些的平台上面做。
...全文
1184 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2019-10-12
  • 打赏
  • 举报
回复
VxWorks ?
GoldWood 2019-10-12
  • 打赏
  • 举报
回复
印刷喷码行业了解一下
赵4老师 2017-03-10
  • 打赏
  • 举报
回复
引用 20 楼 zhao4zhong1 的回复:
想提高实时性,请转行航空航天领域。
正解!
黑娃 2017-03-10
  • 打赏
  • 举报
回复
引用 24 楼 DelphiGuy 的回复:
要求实时,用.net、java是不行的,要用原生代码开发工具,不要用GetTickCount计时,用多媒体计时器回调,精度可以达到毫秒级,而且可以保证当前线程挂起时可以得到响应。
我用的。net的DateTime.Now来计时,不知道它是不是用的GetTickCount实现的,不过从我的例子来看,如果在一个循环里面直接计时什么都不做,它可以精确到0.001ms,对了,我并没有看错,它里面的Tick是一个long型,记录了从1900到现在经过了多少百纳秒。现在想来觉得疑惑,前面不是说windows的计时在12ms吗
黑娃 2017-03-10
  • 打赏
  • 举报
回复
引用 25 楼 tajon1226 的回复:
楼主用.net去开发。。。 你不知道现在VC快要死了,但还死不了的原因吗? 因为在图像和音频处理上,java和C#和c++相比不是同个级别的! “”ls.Add(sp.TotalMilliseconds.ToString());// ls是一个泛型容器,就是这句导致100次耗时记录中,每次记录8、9次就会突然来一次翻倍耗时的“ ” 建议去看下该容器的源码或者使用说明,个人猜测是因为记录8、9次后,空间自动扩容。 没用过。net的库,不知道是否可以一开始先定好内存空间。
我之前也怀疑是容器内存扩充造成了,于是实现分配了30000capacity,结果并无变化,后来验证发现并非容器Add所致,而是那个ToString的方法
黑娃 2017-03-10
  • 打赏
  • 举报
回复
引用 17 楼 zilaishuichina 的回复:
[quote=引用 15 楼 falcomavin 的回复:] 对的,我之前的测试程序确实有问题,每次都算了新开一个线程的时间,肯定有问题。我修改以后,如果只是一般的操作确实比较稳定,只有1ms左右的浮动,很多时候执行时间都是相等的。不过我加了一句容器的add()之后,每执行6、7次,消耗时间就会突然增加1倍: for(int j = 0; j < 100; ++j) { List<string> ls = new List<string>(); for (int i = 0; i < 30000; i++) { DateTime now = DateTime.Now; TimeSpan sp = new TimeSpan(now.Ticks - lastTime.Ticks); ls.Add(sp.TotalMilliseconds.ToString());// ls是一个泛型容器,就是这句导致100次耗时记录中,每次记录8、9次就会突然来一次翻倍耗时的 lastTime = now; } // 记录一次耗时 } 以上是.NET中的表现,不知道为什么会如此,看来像是一些很常见的代码使得运行时间有浮动了,我的算法里面肯定很容易就用到动态容器
.net的话, 应该是和他的内存分配/回收机制有关, 可能每执行8,9次,.net就就行了一次gc操作,于是耗时增加 所以还是像C/C++这种,我的内存我做主的语言,在对程序效率有比较高的要求的情况下,表现要比其他语言好一些 像你的需求,如果存在大量的数组/链表元素的插入删除的情况下,将内存预先分配好,算法执行过程中不再去动态申请释放内存,是一个比较好的方式,说白了,就是用空间换时间[/quote] 后来我验证了这个例子,其实是sp.TotalMilliseconds.ToString()导致了时间波动,如果只是ls.Add(24)之类的并不会造成波动。但.NET确实运行效率在ms级别上的确定性比c++有更多的不可控。 目前看来,我要做的系统要求降低了,只需要在30ms时间内接收22000个字节,然后存在内存里,继续接收,一直重复,至于算法和反馈交给另外一个线程去做,它有更充裕的时间去处理。网络接收22000个字节正常情况下只需要几ms,把它存在一个容器里面10ms左右也无所谓,所以我认为按这个时间计算去处理应该没有问题,就怕os偶然性调度延时会干扰到我这个时间的确定性,我觉得这种情况理论上无法消除,因为是分时os,我只能尽量采用效率高的编程方法去实现。
  • 打赏
  • 举报
回复
引用 28 楼 falcomavin 的回复:
[quote=引用 24 楼 DelphiGuy 的回复:] 要求实时,用.net、java是不行的,要用原生代码开发工具,不要用GetTickCount计时,用多媒体计时器回调,精度可以达到毫秒级,而且可以保证当前线程挂起时可以得到响应。
我用的。net的DateTime.Now来计时,不知道它是不是用的GetTickCount实现的,不过从我的例子来看,如果在一个循环里面直接计时什么都不做,它可以精确到0.001ms,对了,我并没有看错,它里面的Tick是一个long型,记录了从1900到现在经过了多少百纳秒。现在想来觉得疑惑,前面不是说windows的计时在12ms吗[/quote] 单位100ns应该是对应windows的FILETIME,计时精度15ms的是GetTickCount(实际上在单核系统上可以达到10ms),而且计时精度不代表程序可以获得的定时精度,简单说就是不管用什么方法获取时间计数,能不能得到连续均匀变化的结果。
走好每一步 2017-03-06
  • 打赏
  • 举报
回复
楼主用.net去开发。。。 你不知道现在VC快要死了,但还死不了的原因吗? 因为在图像和音频处理上,java和C#和c++相比不是同个级别的! “”ls.Add(sp.TotalMilliseconds.ToString());// ls是一个泛型容器,就是这句导致100次耗时记录中,每次记录8、9次就会突然来一次翻倍耗时的“ ” 建议去看下该容器的源码或者使用说明,个人猜测是因为记录8、9次后,空间自动扩容。 没用过。net的库,不知道是否可以一开始先定好内存空间。
  • 打赏
  • 举报
回复
要求实时,用.net、java是不行的,要用原生代码开发工具,不要用GetTickCount计时,用多媒体计时器回调,精度可以达到毫秒级,而且可以保证当前线程挂起时可以得到响应。
worldy 2017-03-06
  • 打赏
  • 举报
回复
所谓实时性就是要求死得快,反应快。使用汇编语言编写的代码速度最快,其次使用C,再其次使用C++;反应速度还和硬件和操作系统密切相关,不知lz是使用什么硬件平台和软件平台,是否使用多线程,这些都会影响软件的实时性
ForestDB 2017-03-06
  • 打赏
  • 举报
回复
个人觉得LZ谈的是“性能”而不是“实时”。 个人对上下文中的“实时”的理解是:保证在一定时间限制内完成特定功能(这里的一定时间并不是有多快,这里的功能也不是LZ提到的“一次TCP传输”,“一次图像处理”,而是指对中断的响应,完成一次调度)。
bravery36 2017-03-03
  • 打赏
  • 举报
回复
我觉得这个要求的确挺高的,一般的系统都不是为这种级别的响应服务的。别的不说,就算是socket的数据,如果recv的线程没有抢到cpu的话就过去了,除非都很空闲。现在的主流服务器思想都是一台不行上两台,高并发的比较常见。
赵4老师 2017-03-03
  • 打赏
  • 举报
回复
想提高实时性,请转行航空航天领域。
赵4老师 2017-03-03
  • 打赏
  • 举报
回复
Windows系统计时精度≈15ms
zilaishuichina 2017-03-03
  • 打赏
  • 举报
回复
引用 16 楼 falcomavin 的回复:
[quote=引用 14 楼 max_min_ 的回复:] 想想硬件和实时网路环境吧。
是一对一(网线直连)和一个设备通信的,网络传输来回加起来都在100kb之内,千兆网卡应该1、2ms就能完成吧[/quote] 你可以在控制台 ping 你的另一台机器测试一下啊, 比如另一台机器的 ip为 192.168.0.100 你 ping 192.168.0.100 -l 65000 表示用ping命令发送65000字节,看延迟多少就大致可以估算了
zilaishuichina 2017-03-03
  • 打赏
  • 举报
回复
引用 15 楼 falcomavin 的回复:
对的,我之前的测试程序确实有问题,每次都算了新开一个线程的时间,肯定有问题。我修改以后,如果只是一般的操作确实比较稳定,只有1ms左右的浮动,很多时候执行时间都是相等的。不过我加了一句容器的add()之后,每执行6、7次,消耗时间就会突然增加1倍: for(int j = 0; j < 100; ++j) { List<string> ls = new List<string>(); for (int i = 0; i < 30000; i++) { DateTime now = DateTime.Now; TimeSpan sp = new TimeSpan(now.Ticks - lastTime.Ticks); ls.Add(sp.TotalMilliseconds.ToString());// ls是一个泛型容器,就是这句导致100次耗时记录中,每次记录8、9次就会突然来一次翻倍耗时的 lastTime = now; } // 记录一次耗时 } 以上是.NET中的表现,不知道为什么会如此,看来像是一些很常见的代码使得运行时间有浮动了,我的算法里面肯定很容易就用到动态容器
.net的话, 应该是和他的内存分配/回收机制有关, 可能每执行8,9次,.net就就行了一次gc操作,于是耗时增加 所以还是像C/C++这种,我的内存我做主的语言,在对程序效率有比较高的要求的情况下,表现要比其他语言好一些 像你的需求,如果存在大量的数组/链表元素的插入删除的情况下,将内存预先分配好,算法执行过程中不再去动态申请释放内存,是一个比较好的方式,说白了,就是用空间换时间
黑娃 2017-03-03
  • 打赏
  • 举报
回复
引用 14 楼 max_min_ 的回复:
想想硬件和实时网路环境吧。
是一对一(网线直连)和一个设备通信的,网络传输来回加起来都在100kb之内,千兆网卡应该1、2ms就能完成吧
黑娃 2017-03-03
  • 打赏
  • 举报
回复
引用 7 楼 zilaishuichina 的回复:
[quote=引用 6 楼 falcomavin 的回复:] [quote=引用 5 楼 zilaishuichina 的回复:] [quote=引用 3 楼 falcomavin 的回复:] tcp传输在局域网,数据量也在1mb之内,但是这个过程会长期执行,就是不停的取数,计算,回送结果,频率很高,每一次给我的时间都必须控制在十几ms之内,怎样尽量让系统能承担这样的任务
如果你的算法可以保证在5ms以内算完, 加上局域网传输数据,十几ms没压力[/quote] 我担心的是os的表现不稳定,我做了一个简单的实验,60000次循环里面仅仅是记录一些时间信息,总共用时50ms左右,但是这个数字是不稳定的,随便尝试了十几次都有20ms左右的浮动。而我要写的程序肯定不只是如此简单,而且我觉得这个浮动也不完全是本程序引起的,也可能是os自身的调度时间浮动[/quote] 也可能是你的用来做实验的程序 存在大量 用户态/内核态 的切换呢? 也可能是你的用来做实验的程序 存在大量 动态内存分配呢? “仅仅记录时间信息” 也要看你是怎么记录的,调用的是哪个api,如果是这些api本身的测量精度达不到ms级别呢?比如GetTickCount,这个api,他的时间精度大概在15-16毫秒,达不到ms级。 所以即使是你的测试程序,也要具体情况具体分析[/quote] 对的,我之前的测试程序确实有问题,每次都算了新开一个线程的时间,肯定有问题。我修改以后,如果只是一般的操作确实比较稳定,只有1ms左右的浮动,很多时候执行时间都是相等的。不过我加了一句容器的add()之后,每执行6、7次,消耗时间就会突然增加1倍: for(int j = 0; j < 100; ++j) { List<string> ls = new List<string>(); for (int i = 0; i < 30000; i++) { DateTime now = DateTime.Now; TimeSpan sp = new TimeSpan(now.Ticks - lastTime.Ticks); ls.Add(sp.TotalMilliseconds.ToString());// ls是一个泛型容器,就是这句导致100次耗时记录中,每次记录8、9次就会突然来一次翻倍耗时的 lastTime = now; } // 记录一次耗时 } 以上是.NET中的表现,不知道为什么会如此,看来像是一些很常见的代码使得运行时间有浮动了,我的算法里面肯定很容易就用到动态容器
max_min_ 2017-03-03
  • 打赏
  • 举报
回复
想想硬件和实时网路环境吧。
zilaishuichina 2017-03-03
  • 打赏
  • 举报
回复
引用 11 楼 DelphiGuy 的回复:
千兆网传输1MB数据也需要8~10毫秒,他还要“不停的取数,计算,回送结果”,收+处理+发,得按照20~30毫秒来预算。
lz说返回结果,没说返回数据也是1MB 当然,如果lz返回的结果也是1MB,那就需要时间翻一倍
加载更多回复(12)

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧