我有一个以1KHz的速率输出64位二进制数据的设备。我通过第三方DLL通过USB读取设备,将二进制数据转换为浮点数,为其加时间戳,并写入文件。
我现在有以下设置:
int main(int argc, char* argv[])
{
unsigned char Message_Rx[64];
USHORT Bytes_Read=0;
std::ofstream out(argv[1]);
do
{
Result = Comms.USBRead(&Message_Rx[0],&Bytes_Read);
unsigned long now = getTickCount(start);
if(Result != 0)
{
uint16_t msb (Message_Rx[11] & 0xff) \\leftshited 8;
uint16_t lsb (Message_Rx[12] & 0xff);
uint16_t rate = msb | lsb;
char outstring[1024];
sprintf(outstring, "%d\t%.7f", now, (float)rate*0.03125);
out << outstring << "\n";
}
}while(!kbhit());
out.close();
}
(抱歉,格式化与>>
或<<
混淆。
这会在我的桌面上产生完美的效果。似乎没有任何数据丢失,时间戳是连续的,相隔1ms。
143379582 -0.5937500 143379583 -1.5312500 143379584 -1.6250000 143379585 -1.4062500 143379586 -1.1875000 143379587 -1.3437500 143379588 -1.3125000 143379589 -1.3125000 143379590 -1.1562500
但是当我在需要使用的旧笔记本电脑上运行时,我会得到以块显示的时间戳,看起来肯定会丢失一些数据:
143379582 -0.5937500 143379582 -1.5312500 143379582 -1.6250000 143379582 -1.4062500 143379582 -1.1875000 143379593 -1.3437500 143379593 -1.3125000 143379593 -1.3125000 143379593 -1.1562500
有没有办法实现代码的加速,这样我就不会丢失数据?
答案 0 :(得分:1)
要说清楚这一点:对于任何不是英特尔486SX的PC,64kb / s是一个非常可笑的速度。通过USB获得几Mb / s非常适合使用没有任何优化的小型Dollar-a-piece微控制器。 无论出现什么问题,都需要调查,而不是代码。
我不知道Comms
图书馆,但我在那里寻找花费时间的地方。
除此之外,您在屏幕上的打印内容应该比处理时间多出几个数量级,但仍然不应该成为问题。如上所述,1kS / s * 64 b / S对于现代(阅读:最近20年)PC硬件而言 nothing 。
答案 1 :(得分:1)
我建议存储原始数据,直到按键被关闭。按下键后,输出数据。
您想要从高性能代码区域中删除格式和输出。
释放一首歌,当数据完成时,将有足够的时间进行打印。
编辑1:
基于数组的循环队列是保存传入数据的良好数据结构。这将为您提供最后的 N 数据样本。
答案 2 :(得分:0)
每当遇到性能问题时,您的第一步应该是对代码进行分析,以查看代码的哪些部分占用时间。
但是,对于您的代码,我会说主循环不需要打印和字符串处理。我会有一个单独的时间戳数组,在我的主循环中只获取数据。
在按键被击中后,您不再有时间限制,可以处理文件I / O的稍微昂贵的操作并构建字符串。
最后要注意的是,您的操作系统可能正在窃取您的CPU周期。您可能希望尝试以更高的优先级运行代码以排除调度。
如上所述,如上所述,除非您在某些非常复古的硬件上运行,否则您的数据速率应该是可持续的。