简体   繁体   中英

Fast C++ String Output

I have a program that outputs the data from an 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("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. 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. 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.

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. However, I'd need to know more about your input data.

Meanwhile, try to buffer your writes manually: 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. 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. 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.

basically you can't do lots of synrhconous terminal IO on something where you want consistent, predictable performance.

Try printing an \\r at the end of your string instead of the usual \\n -- if that works on your system. 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?

I suggest you format your text to a buffer, then use the fwrite function to write the buffer.

Building off of dasblinkenlight's answer, use fwrite instead of puts . The puts function is searching for a terminating nul character. The fwrite function writes as-is to the console.

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.

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. 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. The latter is 1023 extra function calls.

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'

try to compile the code with the -O3 flag or -O2 (for a safe option)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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