初始化过程根据数据库NumberOfBuffers设置Buffer大小,每个Buffer固定为512×4 Words,每个Words(DSP操作的最小单元)=4 Bytes.
Buffer最小为50,太小对导致当存储通道较多时,上位机没读取完,Buffer又要被写上了,导致溢出,Buffer如果太大,下位机需要开辟更大的内存给Datalogger,有可能避免Buffer的溢出,但受限于上位机的读取能力,读取间隔100ms,每次读取时已经尽可能读取的Buffer中的数据,每次任务可能读取不完该周期内(100ms)所新产生的数据,最终迟早导致Datalogger会溢出。100ms的这个周期内除了Datalogger需要与下位机交互数据,其他还有数据在交互,具体数量不明。
每个Buffer的表头Word存储状态,其余511个Words存储数据,(表头存储状态为BUFFER_OVERRUN = 0x80000000时,表示溢出,其余数字1-1022时表示该Buffer当前已经写入了多少个数据。【1022表示的是双字节数据,实际表示float数据除以2即511个float数据,或16bit的低精度float数据1022个】
基本的流程如下
启动记录数据,DataLoggerThreadRun(),详细过程主要为:WriteBatchTo()写入到数据流。
ReadAvailableBuffers()读取所有表头标记为BUFFER_SIZE_IN_WORDS的Buffer,组成List<Word[]>,最后一个Buffer可能不是满的。读取过程中,已经写满的Buffer的表头进行复位处理buffers[readBuffer][0] = new Word(0),使得下位机后续可以正常擦写该buffer。availableShorts = (int)wordsRead[0].UIntValue进行确定该buffer的有效长度;ReadAvailableBuffers()有可能读到溢出数据跳出循环,但还是被记录到了一个Buffer。FloatLogging = PreferFloatLogging && binaryFileFormat.Supports32BitLogging即采用的是16位记录每个数据。
第二阶段在进行一次处理,AddLowOrderBytesFromWord读取一次低位2字节的半个Word。
6.2. 当下一次读取时,由于上次的最后一个buffer只读取了一部分,而恰好当readIndexInShorts为奇数时,即记录了一个2字节(半个word)的数据,由于后面都是对整个word的四字节数据进行处理,因此该处的lowerIndex减小一个half word,即包含之前的半个和新的半个 word,但前半个不进行存储,需要取第一个字的高位2字节数据进行处理。将++readIndexInShorts进行处理,后面按完整整的4字节下word进行处理。
bytesToWrite【局部变量,本100ms周期的字节数组】readIndexInShorts设定,如果最后是满buffer的,则复位为0,否则置为标识字的数据,便于下次读第一个buffer时,设置准确的起始位置formattedBytes写入到logOutputStream【current position开始写,类似append模式】。上位机读取数据间隔为100ms,读取过程是do-while循环,即在100ms内尽量多的读取buffer,并对表头标识word进行置零复位。
当buffer设置较小时,即100ms的周期内,可能只消耗了少部分时间(几ms)去读,剩下的时间处于线程等待过程,线程等待过程中,下位机DSP不会等待,仍然根据采样率往buffer中写入数据,如果写的过程中发现该buffer的标识word不为0,则报buffer溢出。
2000年制定的USB 2.0标准是真正的USB 2.0,被称为USB 2.0的高速(High-speed)版本,理论传输速度为480 Mbps,即60 MB/s,但实际传输速度一般不超过30 MB/s,采用这种标准的USB设备也比较多。USB 2.0 百度百科
由于HUB与上位机交互时需要连续通讯,实际有效带宽仍然会大幅降低。
考虑到Pulsar上下位机还有其他数据交互,假定系统的通讯带宽的2/3 用于稳定的Datalogger,则只有6.7MB/s带宽用于数据记录。
假定采集buffer的过程时间为(理想情况下不变),同时buffer(大小固定=512Words=2048Byte)采集完后等待,假设采样N=200个信号,采样率为Fs=1024,则每个周期所新产生的数据为
。而实际上上位机从下位机读取数据时,平均每个Buffer所需时间为1.3ms(包含读取数据1ms和数据头的判断处理0.35ms),即读取的速率为,理想状态下为保证平衡
则每ms的读取与写入数据量差为:Buffer_R=-Buffer_W
则
| Name | Result |
|---|---|
| Sample Rate | 1024 |
| Signal Number | 200 |
| CreatBufferNum/ms | 0.400 |
| CreatByteNum/s (MB/s) | 0.819 |
| ReadBufferNum/ms | 0.741 |
| T0(ms) | 100 |
| T1(ms) | 117.39 |
| Total Time/Peroid | 217.39 |
则每个周期内产生的数据量为,即为了保证不溢出,NumberofBuffers参数至少需要87,通常可设置为最低需求的3-4倍,即1024Hz采样200个信号设置为300-350之间比较稳妥,实测设置为200时,大多数也可能正常采集,但偶尔仍然会溢出。
实测时也基本显示,每次读取的Buffer数量在80-100之间,耗时102-140ms之间,与理论计算基本一致。
ReadAvailableBuffers: 87,Eplapsed:107.5648,Transform/Stream 175200,Eplapsed:4.321
ReadAvailableBuffers: 89,Eplapsed:113.1453,Transform/Stream 180000,Eplapsed:5.307
ReadAvailableBuffers: 93,Eplapsed:112.8044,Transform/Stream 188800,Eplapsed:4.2122
ReadAvailableBuffers: 98,Eplapsed:125.869,Transform/Stream 198400,Eplapsed:4.5378
ReadAvailableBuffers: 88,Eplapsed:110.8824,Transform/Stream 177600,Eplapsed:4.0968
ReadAvailableBuffers: 93,Eplapsed:122.3553,Transform/Stream 188000,Eplapsed:4.924
ReadAvailableBuffers: 93,Eplapsed:117.814,Transform/Stream 187200,Eplapsed:5.3667
ReadAvailableBuffers: 103,Eplapsed:138.6704,Transform/Stream 209600,Eplapsed:6.879
ReadAvailableBuffers: 101,Eplapsed:138.688,Transform/Stream 203200,Eplapsed:7.1314
ReadAvailableBuffers: 96,Eplapsed:127.5691,Transform/Stream 194400,Eplapsed:6.2587
ReadAvailableBuffers: 110,Eplapsed:150.7269,Transform/Stream 223200,Eplapsed:5.7377
ReadAvailableBuffers: 99,Eplapsed:133.2098,Transform/Stream 200800,Eplapsed:6.0722
ReadAvailableBuffers: 100,Eplapsed:133.3538,Transform/Stream 202400,Eplapsed:4.8707
ReadAvailableBuffers: 100,Eplapsed:131.0687,Transform/Stream 202400,Eplapsed:5.4731
ReadAvailableBuffers: 96,Eplapsed:119.0361,Transform/Stream 193600,Eplapsed:6.3919
ReadAvailableBuffers: 96,Eplapsed:123.551,Transform/Stream 194400,Eplapsed:4.7678
ReadAvailableBuffers: 86,Eplapsed:102.7466,Transform/Stream 173600,Eplapsed:5.4833
ReadAvailableBuffers: 90,Eplapsed:108.6169,Transform/Stream 181600,Eplapsed:4.4403
ReadAvailableBuffers: 91,Eplapsed:116.5304,Transform/Stream 184000,Eplapsed:4.1699
ReadAvailableBuffers: 97,Eplapsed:122.5551,Transform/Stream 196800,Eplapsed:4.8038
ReadAvailableBuffers: 98,Eplapsed:130.661,Transform/Stream 198400,Eplapsed:5.3829
ReadAvailableBuffers: 98,Eplapsed:126.5786,Transform/Stream 197600,Eplapsed:5.8669
ReadAvailableBuffers: 97,Eplapsed:119.0659,Transform/Stream 196800,Eplapsed:4.9297
ReadAvailableBuffers: 89,Eplapsed:106.1763,Transform/Stream 180000,Eplapsed:4.3001
ReadAvailableBuffers: 86,Eplapsed:101.6183,Transform/Stream 173600,Eplapsed:3.9981
ReadAvailableBuffers: 89,Eplapsed:106.5956,Transform/Stream 179200,Eplapsed:4.5421
ReadAvailableBuffers: 93,Eplapsed:118.8422,Transform/Stream 188000,Eplapsed:4.4214
由的计算公式可得,式中对非常敏感,如果在某一个过程中下降了,即读取一个buffer的时间增加了,比如由1.35ms增加到2ms,即,则在该周期内产生200个buffer,如果比如由1.35ms增加到2.35ms,即,则在该周期内产生667个buffer,该过程并非线性,因此对于性能较差的电脑,抖动加大的情况下,该过程更容易溢出,增大Buffer的数量,可以缓解,但仍然不能完全避免溢出。
以160个信号,采样率 2kHz为例,每秒生成的数据量buffer为为$160*4 Byte /4 *2048/1000/512= 0.64 buffer/ms < 0.741 T_1=$)需产生数据buffer为471:
但考虑到读取数据过程中的抖动,该过程仍然会导致buffer ( NumberOfBuffers=500)溢出进一步增加Buffer Number可能更进一步消化采样峰值,有可能能够避免buffer溢出,实测700仍然会溢出,调整到800-1200则勉强可以运行,但不是很稳定,此时如果运行了其他的Datalogger,则很容易导致溢出,调整至1800则基本可以正常运行,但平均每一次读取耗时超过700ms。
| Name | Result |
|---|---|
| Sample Rate | 2048 |
| Signal Number | 160 |
| CreatBufferNum/ms | 0.640 |
| CreatByteNum/s (MB/s) | 1.311 |
| ReadBufferNum/ms | 0.741 |
| T0(ms) | 100 |
| T1(ms) | 635.29 |
| Total Time/Peroid | 735.29 |
ReadAvailableBuffers: 501,Eplapsed:629.2596,Transform/Stream 1022080,Eplapsed:25.9833
ReadAvailableBuffers: 442,Eplapsed:556.3342,Transform/Stream 901760,Eplapsed:24.1502
ReadAvailableBuffers: 413,Eplapsed:515.4335,Transform/Stream 841600,Eplapsed:20.8657
ReadAvailableBuffers: 418,Eplapsed:518.0167,Transform/Stream 852480,Eplapsed:24.5328
ReadAvailableBuffers: 421,Eplapsed:519.2405,Transform/Stream 858240,Eplapsed:23.0533
ReadAvailableBuffers: 468,Eplapsed:594.0704,Transform/Stream 954880,Eplapsed:26.2324
ReadAvailableBuffers: 456,Eplapsed:572.6483,Transform/Stream 929920,Eplapsed:28.7945
ReadAvailableBuffers: 444,Eplapsed:547.0852,Transform/Stream 905600,Eplapsed:23.8223
ReadAvailableBuffers: 435,Eplapsed:541.4682,Transform/Stream 887040,Eplapsed:39.4905
ReadAvailableBuffers: 512,Eplapsed:642.8361,Transform/Stream 1044480,Eplapsed:30.7062
ReadAvailableBuffers: 468,Eplapsed:582.3194,Transform/Stream 954880,Eplapsed:27.7863
ReadAvailableBuffers: 442,Eplapsed:555.2881,Transform/Stream 901120,Eplapsed:25.019
ReadAvailableBuffers: 517,Eplapsed:676.5783,Transform/Stream 1054720,Eplapsed:32.177
ReadAvailableBuffers: 537,Eplapsed:689.7283,Transform/Stream 1095680,Eplapsed:33.3914
ReadAvailableBuffers: 1016,Eplapsed:1434.4375,Transform/Stream 2074880,Eplapsed:76.8432
ReadAvailableBuffers: 912,Eplapsed:1232.9305,Transform/Stream 1861760,Eplapsed:54.005
ReadAvailableBuffers: 794,Eplapsed:1073.6983,Transform/Stream 1621120,Eplapsed:62.1076
ReadAvailableBuffers: 1051,Eplapsed:1460.1503,Transform/Stream 2145920,Eplapsed:79.5791
ReadAvailableBuffers: 692,Eplapsed:891.77,Transform/Stream 1412480,Eplapsed:69.0511
ReadAvailableBuffers: 768,Eplapsed:1021.2466,Transform/Stream 1568000,Eplapsed:53.3589
ReadAvailableBuffers: 840,Eplapsed:1150.2863,Transform/Stream 1714560,Eplapsed:56.4592
ReadAvailableBuffers: 818,Eplapsed:1108.7819,Transform/Stream 1669760,Eplapsed:55.4529
ReadAvailableBuffers: 766,Eplapsed:1037.6374,Transform/Stream 1564160,Eplapsed:71.4258
ReadAvailableBuffers: 754,Eplapsed:1001.6971,Transform/Stream 1539200,Eplapsed:47.5649
ReadAvailableBuffers: 667,Eplapsed:878.2846,Transform/Stream 1360640,Eplapsed:48.0114
ReadAvailableBuffers: 585,Eplapsed:751.799,Transform/Stream 1194240,Eplapsed:37.6162
ReadAvailableBuffers: 573,Eplapsed:739.4109,Transform/Stream 1169280,Eplapsed:43.0077
ReadAvailableBuffers: 491,Eplapsed:618.7171,Transform/Stream 1001600,Eplapsed:29.9025
ReadAvailableBuffers: 481,Eplapsed:606.2664,Transform/Stream 981120,Eplapsed:26.2456
ReadAvailableBuffers: 467,Eplapsed:589.86,Transform/Stream 952320,Eplapsed:31.3184
ReadAvailableBuffers: 500,Eplapsed:638.3661,Transform/Stream 1020160,Eplapsed:27.554
ReadAvailableBuffers: 503,Eplapsed:641.4854,Transform/Stream 1025920,Eplapsed:34.5002
当Datalogger 记录的数据量太大,出现A buffer overrun occurred报警时,可以通过以下方式解决:
1)如果长时间记录数据可减少记录数据的通道数;
2)可以减小数据记录的采样频率;
3)适当增大datalogger的数据缓存空间
如果增加的过大,虽然记录较多信号时Buffer不会溢出,则会导致每个100ms周期内,能够被读取的buffer太多,USB带宽大部分都被Datalogger占用,其他比如Monitor会更新卡滞,Scope可能采集不到足够的数据等故障。
4)电脑使用时间太长的话,需更换电脑。