简体   繁体   English

快速 C++ 字符串 Output

[英]Fast C++ String Output

I have a program that outputs the data from an FPGA.我有一个从 FPGA 输出数据的程序。 Since the data changes EXTREMELY fast, I'm trying to increase the speed of the program.由于数据变化非常快,我正在尝试提高程序的速度。 Right now I am printing data like this现在我正在打印这样的数据

for (int i = 0; i < 100; i++) {
    printf("data: %d\n",getData(i));
}

I found that using one printf greatly increases speed我发现使用一个 printf 大大提高了速度

printf("data: %d \n data: %d \n data: %d \n",getData(1),getData(2),getData(3));

However, as you can see, its very messy and I can't use a for loop.但是,正如您所看到的,它非常混乱,我不能使用 for 循环。 I tried concatenating the strings first using sprintf and then printing everything out at once, but it's just as slow as the first method.我尝试先使用sprintf连接字符串,然后一次打印所有内容,但它与第一种方法一样慢。 Any suggestions?有什么建议么?

Edit: I'm already printing to a file first, because I realized the console scrolling would be an issue.编辑:我已经先打印到文件,因为我意识到控制台滚动会是一个问题。 But its still too slow.但是还是太慢了。 I'm debugging a memory controller for an external FPGA, so the closer to the real speed the better.我正在为外部FPGA调试memory controller,所以越接近真实速度越好。

If you are writing to stdout, you might not be able to influence this all.如果您正在写入标准输出,您可能无法影响这一切。

Otherwise, set buffering否则,设置缓冲

Now, Boost Karma is known to be pretty performant.现在,众所周知,Boost Karma 的性能非常好。 However, I'd need to know more about your input data.但是,我需要更多地了解您的输入数据。

Meanwhile, try to buffer your writes manually: Live on Coliru同时,尝试手动缓冲您的写入: Live on Coliru

#include <stdio.h>

int getData(int i) { return i; }

int main()
{
    char buf[100*24]; // or some other nice, large enough size
    char* const last = buf+sizeof(buf);
    char* out = buf;

    for (int i = 0; i < 100; i++) {
        out += snprintf(out, last-out, "data: %d\n", getData(i));
    }

    *out = '\0';
    printf("%s", buf);
}

Wow, I can't believe I didn't do this earlier.哇,我不敢相信我没有早点这样做。

const int size = 100;
char data[size];
for (int i = 0; i < size; i++) {
    *(data + i) = getData(i);
}

for (int i = 0; i < size; i++) {
    printf("data: %d\n",*(data + i));
}

As I said, printf was the bottleneck, and sprintf wasn't much of an improvement either.正如我所说, printf是瓶颈,而sprintf也没有太大的改进。 So I decided to avoid any sort of printing until the very end, and use pointers instead所以我决定直到最后都避免任何形式的打印,而是使用指针

How much data?多少数据? Store it in RAM until you're done, then print it.将其存储在 RAM 中,直到完成,然后打印。 Also, file output may be faster.此外,文件输出可能会更快。 Depending on the terminal, your program may be blocking on writes.根据终端的不同,您的程序可能会阻塞写入。 You may want to select for writeability and write directly to STDOUT, instead.您可能希望选择可写性并直接写入 STDOUT。

basically you can't do lots of synrhconous terminal IO on something where you want consistent, predictable performance.基本上你不能在你想要一致的、可预测的性能的东西上做大量的同步终端 IO。

Try printing an \\r at the end of your string instead of the usual \\n -- if that works on your system.尝试在字符串末尾打印一个\\r而不是通常的\\n - 如果这适用于您的系统。 That way you don't get continuous scrolling.这样你就不会连续滚动。

It depends on your environment if this works.这是否有效取决于您的环境。 And, of course, you won't be able to read all of the data if it's changing really fast.而且,当然,如果数据变化非常快,您将无法读取所有数据。

Have you considered printing only every n th entry?您是否考虑过仅打印第n个条目?

I suggest you format your text to a buffer, then use the fwrite function to write the buffer.我建议您将文本格式化为缓冲区,然后使用fwrite函数写入缓冲区。

Building off of dasblinkenlight's answer, use fwrite instead of puts .基于 dasblinkenlight 的答案,使用fwrite而不是puts The puts function is searching for a terminating nul character. puts函数正在搜索终止 nul 字符。 The fwrite function writes as-is to the console. fwrite函数按原样写入控制台。

char buf[] = "data: 0000000000\r\n";
for (int i = 0; i < 100; i++) {
    // int portion starts at position 6
    itoa(getData(i), &buf[6], 10);

    // The -1 is because we don't want to write the nul character.
    fwrite(buf, 1, sizeof(buf) - 1, stdout);
}

You may want to read all the data into a separate raw data buffer, then format the raw data into a "formatted" data buffer and finally blast the entire "formatted" data buffer using one fwrite call.您可能希望将所有数据读入单独的原始数据缓冲区,然后将原始数据格式化为“格式化”数据缓冲区,最后使用一次fwrite调用炸毁整个“格式化”数据缓冲区。

You want to minimize the calls to send data out because there is an overhead involved.您希望尽量减少发送数据的调用,因为这涉及到开销。 The fwrite function has about the same overhead for writing 1 character as it does writing 10,000 characters. fwrite函数写入 1 个字符的开销与写入 10,000 个字符的开销大致相同。 This is where buffering comes in. Using a 1024 buffer of items would mean you use 1 function call to write 1024 items versus 1024 calls writing one item each.这就是缓冲的用武之地。使用 1024 个项目缓冲区意味着您使用 1 个函数调用来写入 1024 个项目,而 1024 个调用则每个写入一个项目。 The latter is 1023 extra function calls.后者是 1023 个额外的函数调用。

I never work with FPGA's so I don't know if will work, but using the optimization flags can improve the for speed with 'loop unrolling'我从不使用 FPGA,所以我不知道是否可行,但使用优化标志可以通过“循环展开”提高 for 速度

try to compile the code with the -O3 flag or -O2 (for a safe option)尝试使用-O3标志或-O2编译代码(为了安全选项)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM