7

我有一个从 FPGA 输出数据的程序。由于数据变化非常快,我正在尝试提高程序的速度。现在我正在打印这样的数据

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

我发现使用一个 printf 可以大大提高速度

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

但是,正如您所看到的,它非常混乱,我不能使用 for 循环。我尝试先使用连接字符串sprintf,然后一次打印所有内容,但它与第一​​种方法一样慢。有什么建议么?

编辑:我已经先打印到文件,因为我意识到控制台滚动会是一个问题。但是还是太慢了。我正在为外部 FPGA 调试内存控制器,所以越接近真实速度越好。

4

5 回答 5

6

如果您正在写入标准输出,您可能无法影响这一切。

否则,设置缓冲

现在,众所周知,Boost Karma 的性能非常好。但是,我需要更多地了解您的输入数据。

同时,尝试手动缓冲您的写入: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);
}
于 2013-08-23T21:42:18.943 回答
4

哇,我不敢相信我之前没有这样做。

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));
}

正如我所说,printf这是瓶颈,sprintf也没有太大的改进。所以我决定在最后避免任何形式的打印,而是使用指针

于 2013-09-05T20:11:19.593 回答
1

多少数据?将其存储在 RAM 中,直到完成,然后打印。此外,文件输出可能会更快。根据终端,您的程序可能会阻止写入。您可能希望选择可写性并直接写入 STDOUT。

基本上你不能在你想要一致的、可预测的性能的东西上做很多同步终端 IO。

于 2013-08-23T21:33:10.070 回答
0

尝试\r在字符串末尾打印一个而不是通常的\n- 如果这适用于您的系统。这样你就不会连续滚动。

这是否有效取决于您的环境。当然,如果数据变化非常快,您将无法读取所有数据。

您是否考虑过只打印每n个条目?

于 2013-08-23T22:54:59.463 回答
0

我建议您将文本格式化为缓冲区,然后使用该fwrite函数写入缓冲区。

根据 dasblinkenlight 的回答,使用fwrite而不是puts. 该puts函数正在搜索终止 nul 字符。该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);
}

fwrite您可能希望将所有数据读入一个单独的原始数据缓冲区,然后将原始数据格式化为一个“格式化”数据缓冲区,最后使用一次调用 来爆破整个“格式化”数据缓冲区。

您希望最大限度地减少发送数据的调用,因为这涉及到开销。该fwrite函数写入 1 个字符的开销与写入 10,000 个字符的开销大致相同。这就是缓冲的用武之地。使用 1024 个项目缓冲区意味着您使用 1 个函数调用来写入 1024 个项目,而 1024 个调用每个都写入一个项目。后者是 1023 个额外的函数调用。

于 2013-08-23T23:26:32.390 回答