簡體   English   中英

nanopb - 如何優化編碼以提高運行時速度

[英]nanopb - how to optimize encoding for runtime speed

我正在使用nanopb在嵌入式系統上進行日志記錄:我的日志記錄消息將是.proto消息。
編碼速度是最重要的因素; 我有足夠的內存和 flash。

問題
具體到nanopb ,如何最大限度地減少編碼時間?

我知道我可以進行的所有 C 優化:內聯函數,在 RAM 中設置pb_encode函數而不是 flash 等

如果我在.proto文件中使用所有固定大小的類型會有所不同嗎?

我知道的簡單方法是:

  • 編碼為 memory 緩沖區並在編譯時啟用PB_BUFFER_ONLY
  • 如果平台是 little-endian 且字節大小是 8 位,則可以定義PB_LITTLE_ENDIAN_8BIT 不過,它應該在大多數編譯器上自動檢測到。
  • 在您的消息定義中,盡量減少子消息的數量。 它們需要單獨的尺寸計算,這需要時間。

這些可能會導致速度提高多達 2 倍。


通過編程對編碼函數的直接調用,而不是通過消息結構和描述符循環,還可以進一步加快編碼速度。 我希望這可以將編碼速度提高到 5 倍。 需要一些關於protobuf 編碼規范的知識。

例如,對於此消息:

message LogMessage {
    uint64 timestamp = 1;
    float batterylevel = 2;
    string logmessage = 3;
}

你可以這樣做:

void writelog(const char *logmsg)
{
    uint8_t buffer[256];
    pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));

    // Get system state
    uint64_t timestamp = get_system_timestamp();
    float batterylevel = get_batterylevel();

    // Encode timestamp
    pb_encode_tag(&stream, PB_WT_VARINT, LogMessage_timestamp_tag);
    pb_encode_varint(&stream, timestamp);

    // Encode battery level
    pb_encode_tag(&stream, PB_WT_32BIT, LogMessage_batterylevel_tag);
    pb_encode_fixed32(&stream, &batterylevel);

    // If we have explicit message, encode it also.
    if (logmsg)
    {
       pb_encode_tag(&stream, PB_WT_STRING, LogMessage_logmessage_tag);
       pb_encode_string(&stream, logmsg, strlen(logmsg));
    }

    // Save the encoded message data to storage
    save_log(buffer, stream.bytes_written);
}

雖然這會導致消息定義的部分硬編碼,但 protobuf 消息的向后和向前兼容性照常工作。 標記號可以通過 nanopb 生成器生成的Message_field_tag宏訪問。 字段類型在 C 代碼中定義,但它們也嵌入在編碼消息中,因此將在解碼端檢測到任何不匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM