《linux高手网络编程遇到的问题.pdf》由会员分享,可在线阅读,更多相关《linux高手网络编程遇到的问题.pdf(6页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、 首页|新手园地|系统管理|编程问题|网络问题|服务器应用|数据库应用|集群和虚拟机|内核源码|文章精选 当前位置:首页编程问题 正文 高手的经验:Linux网络通信程序中,最快的数据发送和接收速度能达到的多少?高手的经验:Linux网络通信程序中,最快的数据发送和接收速度能达到的多少?发布时间:2010-06-03 字体:大 中 小 关键字:it-rocketit-rocket 说 因为最近在linux下调试A/D以100ksps采样率进行采样并将数据通过socket或者RPC两种不同的通信程序发送到windows客户端时,发觉采样出来的数据网络传输得很慢,导致板子上开辟的缓冲区溢出,数据丢
2、失。但又不知道该怎样极大地提高网络速度才能更好地将数据传输过来。请大家提提意见。每秒100k的采样率,其数据量有:100k*4=400kByte=3.2Mbps 开发板的网卡速率为10M/100Mbps。该程序只能使用TCP来传输。此外想请教大家通过setsockopt等设置socket之后,能达到的最快的数据发送、接收速率能达到多少?是怎么做到的?非常感谢。ShadowStarShadowStar 说 建议你将数据合并发送。按照你的说法,100k4400KByte。也就是说,每个采样只有4Byte。也就是说,如果每个采样都发送一次报文的话,也就是需要100Kpps的发送速度。一般的开发板子的
3、处理器很难达到这个速度。it-rocketit-rocket 说 ShadowStar 理解错我的意思了。1秒钟能采样出100000即100k个点,每个点占4个字节大小,我在RPC机制下发送时,可以选择每次发送1024个或者4096个,异或8192个数据这几个不同的值。但是仍然出现板上缓冲区不断堆积数据,最后溢出。TCP socket程序的情况也差不多。所以我认为要提高网络传输速度,但不知道该如何入手。ShadowStarShadowStar 说 如您所述,我认为现象有点不太正常。我建议您查看一下CPU负载,是不是100%了?如果是的话,是不是都被采样程序占用了?3.2Mbps的流量还是不大的
4、,如果只有几个报文的话。it-rocketit-rocket 说 ShadowStar 不愧是Star啊!呵呵 非常感谢。您的推测真的非常的到位,虽然该程序所占的CPU没有完全达到100%,但是该程序所构成的5个线程的CPU之和高达98%。其中 T1(应该是我的采集线程,优先级最高)为89.7%;T2(怀疑是我的处理数据线程)占8.2%,T3占了0.1%,T4占了0.0%,T5占了0.1%。其中top命令占了1.7%。总的CPU几乎有99。此外五个线程占得内存比例均为27.4%。其实在我的程序中,我只开了3个线程(采集、数据处理、准备发送数据到发送缓冲区),此外还有main线程,多出了的一个线
5、程,我也不太清楚是怎么回事。采集线程只是按时准确地去采集获得一组数据,所以里边有一个usleep的休眠,有20.48ms(这个时间不精确,我也有些头疼),采集出来的数据放入FIFO1中,就不干其他活儿了。数据处理线程将FIFO1中的数据转换且经过数据处理后放入FIFO2中,用于发送。准备发送数据到发送缓冲区线程将数据填入发送缓冲区待发送,main线程完成数据发送的功能,这是RPC机 热点文章热点文章Linux 多线程内存释放问题 急:编译链接的问题 canno grep区分大小写问题 linux下面如何查看一个进 请教:为什么此处非要-o r 指针数组初始化问题 matlab 2010a li
6、nux 下载 STL list erase删除后怎么 关于strcpy以及strncpy的 dlopen 的搜索路径的问题 相关文章相关文章程序阻塞在了 recvfrom,线程取消pthread_cancel 开发板无法挂载nfs到vmwar 请问文件加密时怎样做才能 弱弱问一下如何写这个协议 伟创力Linux C语言/SQL C+上海Linux C语言开发薪资 UNIX编程遇到的函数用法上 Page 1 of 6高手的经验:Linux网络通信程序中,最快的数据发送和接收速度能达到的多少.2011-11-8http:/ 说 不好意思,我是做内核开发的,对于应用层开发不是很熟。不过如果你的需求放
7、在内核态来做的话,应该说是很容易的。it-rocketit-rocket 说 呵呵,没有关系的,你已经给了我很大的提示了,明天回公司改改采集线程的休眠时间,让它多让出些CPU的时间,估计效果会有所提高。CPU被占用了绝大部分,应该会影响到数据发送等操作的其他线程,我估计这里会是我的突破口!呵呵 放在内核态来做,你能谈谈思路吗?如果需要的话,我看是否需要改进这个东西,主要是自己对内核没有深入去研究过,呵呵 感激不尽!我的需求很简单:采集板卡的数据-进行一些滤波等数据处理-将数据一个都不能丢地网络传送到Windows系统的客户端。ShadowStarShadowStar 说 在内核态处理的大体流程
8、就是,用一个定时器定时采集数据,然后封包丢出去,over。当然,我说的是比较简单的流程,根据实际需求,可能还需要做一些队列等处理。it-rocketit-rocket 说 恩,非常感谢。我还需要继续学习,对这内核态的操作不是很熟悉,呵呵!据其他高手的分析,这个问题有两种:第一种:hzcpig:“采样线程中,usleep级别下的while(1)cpu占用是很恐怖的,不能改近下采集方式,通过select,poll之类比较友善的方式么。如果采集数据的时间不确定,最好的方式不是去实时轮询,最好是在数据处设中断或回调,主动通知。”我的问题:其实硬件提供了两个中断INT1和INT2,其中INT2用于告知F
9、IFO硬件存储器半满,在中断程序中就可以取数。INT1用于其它按键中断,我在驱动中用kill_async发送SIGIO异步信号通知给我的APP,在APP中对按键用信号处理函数对SIGIO信号做了相应的处理。而对这个INT2半满中断,我在驱动中却没有利用,而用了上面的延时等待取数的方式,所以影响了整个程序的效率。由于我对这个异步信号通知不是很熟悉,是否我也应像处理INT1的那种信号通知APP的处理方式?发送给APP的信号为SIGURG或者说SIGUSR1等,会有问题吗?非常感谢。第二种:yanjinbin0“先停掉其他进程,用测试数据通过socket发送,看其是否支持3.2Mbps/s的速率发送
10、.如果行在慢慢优化,如果这样都行,那你的考虑压缩传输了.”“建议先做下这个验证,因为这个验证顶多只要一天时间就完了,否则光靠想象,左改右改下,或许某些偶然的场合会解决问题,但大部分还是要回到原来的步骤,一个步骤一个步骤来验证.最好确定问题在来.”但是 由于目前时间比较急,我还没有进行验证,虽然我程序是RPC通信程序。aaaaa5aaaaaaa5aa 说 好聪明,放在内核态来做的提法真的不错,等下验证 it-rocketit-rocket 说 这确实很值得我考虑这种方法。我想问一下,内核态里从驱动中把数据取回来一次能返回给APP的内存块大小,有限制吗?smallocsmalloc 说 Page
11、2 of 6高手的经验:Linux网络通信程序中,最快的数据发送和接收速度能达到的多少.2011-11-8http:/ 另一个帖子也看了。既然这边人关注的多.就在这边讨论好了.很明显是usleep占用时间太多了:while(1)usleep(20480);/调用驱动的取数接口./将数据填入FIFO1缓冲中.ShadowStar 说的方法是正确的做法 看你时间好象来不急.最简单的可行的解决方案应该是 完成变量 LKD中文第2版118页 去掉usleep 直接在驱动读函数对应的内核函数内添加wait_for_compleition()int2中断函数中加completion()我对完成变量喊不是很
12、了解.不知道中断函数里能不能调用completion().it-rocketit-rocket 说 感谢smalloc和Shadowstar等的分析和建议,我查查相关资料,使用它的半满中断改进一下采样的效率,降低这个采样线程占用CPU的使用率。此外我验证了一下,在停掉采样线程之后,其他线程正常时,数据传输能达到大约4.0Mbps,所以是否确认没有什么问题?smallocsmalloc 说 有没有问题.我不知道咋说.先申明下我上的给的完成变量似乎不一定行.首先是中断里是否能调用completion()的问题 然后是你的采样读周期大概是2ms,而通常一个时间片为10ms.是否提高效率要,节省CPU
13、资源要看一个调度函数大概需要多少时间运行了.然后是你说的4M绝对不是有线的速率的上限.最少也能达到7M 如果没有等待采样耗时,那么只能是处理器运算耗时了.曾经接触过一个软件方法加密的东西。也是因为处理器加密运算瓶颈导致传输率低.这个时候应该看到你的处理器仍然占很高的使用率.另外在应用层处理数据也会因为进程切换导致一个数据包处理时间变长.在处理器满负荷工作下的传输率,就是你能采样处理的最大传输率.采样本身应该占用及少的处理器时间.所有的处理器资源应该尽量分配在数据处理算法.这样才是最有效的.aaaaa5aaaaaaa5aa 说 分析的真是透彻,深入学习 it-rocketit-rocket 说
14、谢谢smalloc的细致分析。A/D在100ksps的采样率下,一个点的采样周期为10us,所以以前的在APP中的做法就是usleep休眠20480微秒后,APP一次从driver中读取2048个采样点放入FIFO1中,紧接着在休眠20480微秒,去取下一批数据,有些遗憾的是该休眠时间有时候会多出1万多微秒,所以这在APP中休眠等待取数的时间不够精确,且该采样线程占用CPU也在90%左右。用shadowStar的建议,用硬件发出的硬件缓冲区半满信号INT2,来在驱动的中断处理程序中进行取数,这半满大概会花上160ms才能出一次中断。较无奈的是我已经在该driver中注册了前面所讲的按键中断IN
15、T1,并可以异步通知我的APP对该按键做些相应。若再在这同一个driver中安装INT2中断,同时在一个driver中存在两个中断号,似乎不行?或者我该改进该driver,另外写一个driver,分别将这两个中断放在不同的两个驱动设备中,进行处理?上面测出来的网传速度4Mbps,可能是因为我还有其他线程的影响吧?若把其他线程都关掉,只进行数据发送,可能会达到你所说的这个速度。其实在我的数据处理线程中,我都把滤波这些都给关了,只是将采样线程中放在FIFO1的采样值转换为电压值放在FIFO2中而已,所以处理步骤是很简化的了。然后另外一个线程只是将FIFO2中的一定量的数据放入发送缓冲区中,main
16、线程在有Windows客户端读取数据时,将数据发送出去而已。Page 3 of 6高手的经验:Linux网络通信程序中,最快的数据发送和接收速度能达到的多少.2011-11-8http:/ 说 一个driver中可以注册有2个中断号,还有我前面看错了你的是20ms所以如果完成变量可用,就值得一试.usleep就是忙等待 it-rocketit-rocket 说 恩,好的,我查查资料试试。呵呵 非常感谢!其实那20480微秒,是针对我APP决定一次取2048个数来讲的,如果决定取其他个数(比如1024、4096),只需要控制不同的休眠时间(10240us、40960us)。另外你说的usleep
17、是忙等待,但我查看usleep的定义,确是说调用该函数的线程被suspended了呢?难道是内核代码对它的实现不是这样的?“The usleep()function will cause the calling thread to be suspended from execution until either the number of real-time microseconds specified by the argument useconds has elapsed or a signal is delivered to the calling thread and its acti
18、on is to invoke a signal-catching function or to terminate the process.The suspension time may be longer than requested due to the scheduling of other activity by the system.”smallocsmalloc 说 记错了.记成udelay了.usleep的确实会睡眠.不过比较奇怪它是如何实现的.按道理说.不应该存在小于一个1/HZ(10ms)的睡眠精确度.这是在C版一个高精确度睡眠的讨论 http:/ 不过问题又来了.到底是为
19、什么占用那么多CPU资源?还有你确信T1是采集进程吗?T1,T2没有反掉?丢失数据的原因还可能是你采集进程睡过头了.()根据上面的精确度推断存在这种可能).还有你的数据处理算法到底能适应多大的数据流量?可不可能说下是什么算法?如果你的处理器只有200MHZ很有可能应付不过来.it-rocketit-rocket 说 呵呵 我看了一下lkd中的完成变量,它说是类似于同步在内核中的实现,由于对内核编程还不熟悉,用起来还真让我头疼,基本还没有什么思路。在驱动的INT2中断中进行数据获取,那它中断一次就有32kB的数据可以取了。但这32KB的数据要如何传到我的APP中才是最好的呢?smallocsma
20、lloc 说 之前分析有误,没搞清楚usleep.看我上面的编辑后的帖子 交互效率最高的mmap 你的数据量不是很大,你原先的那方式我想就可以了.问题在于中断中如何通知应用层数据已经接受到.其实前面的你帖子里别人给的就是方法.问题是数率低会不会是你算法占用时间的问题。你应该做下算法+发送数据的实验.不采集.it-rocketit-rocket 说 呵呵 还是smalloc推测的正确!经过测试,确实是我把线程所占CPU的使用率搞错了。正确顺序是:Page 4 of 6高手的经验:Linux网络通信程序中,最快的数据发送和接收速度能达到的多少.2011-11-8http:/ 说 路过看看!duan
21、jigangduanjigang 说 标注下,大家多多讨论交流啊:wink:it-rocketit-rocket 说 呵呵 谢谢版主。it-rocketit-rocket 说 当我屏蔽掉转换电压的那部分调用之后,数据的网络传输速度确实提高了许多,而且各个线程,包括数据处理线程,它们的CPU占有量都差不了太多。听取了老总和其他同事的建议后,改进了转换电压函数的实现和调用方式,测试之后,虽然在100ksps情况下,还存在1分钟采样缺少70万左右的数据量,但可能这个问题的解决更多还是应该继续优化程序的一些实现算法和提高性能上。smallocsmalloc 说 缺少是指数据丢失?如果是,那么看我前面提
22、到的,usleep方式的问题.虽然是US级别的.但是C版有人实验过休眠的最小其实为一个1/1HZ.那么就是10ms,那其实你的是休眠30ms,所以大约丢失1/3.当然这个还没考虑精确的切换时间.,其实一般硬件来的做法是用中断程序处理接收到的数据才不会有丢失.it-rocketit-rocket 说 不好意思,因为这两天去调试另外的一个新仪器了,所以这个很忙急的问题也就落下了些时间。这1分钟缺少的70万左右的数据,也就是缺少大约7秒左右的采样时间。数据从硬件的角度来讲,应该是不存在丢失,因为这个老总和另一位硬件老工程师验证过,丢失数据,绝大部分原因就是我程序(采样线程)从驱动中读取数据慢了,让硬
23、件的buffer溢出了。哪天和老总他们讨论过,从半满中断中取数,一次中断就会有32k*2=64kByte的数据量需要从驱动的中断中读回来,那位老硬件工程师认为这数据量在采集时间一长,稍不注意也会数据溢出。所以他认为用目前这种读数方式还是可以,减少数据的拷贝,但这个休眠的时间(20480微秒)在程序中确实不好精确控制,我都是从统计中获得大概需要休眠多少时间,来大约的设置休眠时间,所以这里也存在的问题。it-rocketit-rocket 说 想了几个方法来解决上述的问题,但是还是未能得到好的答案。应该还会采用半满中断来处理这个采集,有不明白的地方,还请大家多多指教,非常感谢。返回顶部 打印本页 关闭窗口 Page 5 of 6高手的经验:Linux网络通信程序中,最快的数据发送和接收速度能达到的多少.2011-11-8http:/ 2009 VrL FAQ VrLinux FAQ,unix,web,数据库,服务器,集群负载均衡Page 6 of 6高手的经验:Linux网络通信程序中,最快的数据发送和接收速度能达到的多少.2011-11-8http:/
限制150内