【问题标题】:Optimizing .hex file size for embedded programming为嵌入式编程优化 .hex 文件大小
【发布时间】:2016-01-08 18:02:00
【问题描述】:

预期平台:Teensy 3.1(微控制器)

IDE:代码块

当前工具链:GNU

当前 .cpp 文件大小:~ 3kb

当前 .hex 文件大小:~ 950kb

考虑到相应的 .cpp 只有 ~ 3kb,这个 .hex 文件的大小似乎大得不合理,这正常吗?我知道 .hex 会更大,但会大 300 倍?天哪。

程序在我的计算机上按预期编译和运行,所以没有问题。

除了使用 Arduino IDE 将一些简单的草图加载到 UNO 上之外,我几乎没有嵌入式编程经验,因此任何关于简化我的程序的指针将不胜感激。这个问题可以在 C++ 代码中解决,还是我可以实现其他途径/工具链来解决这个问题?

参考代码:

#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>

using namespace std;

int main() {

double hidden_out = 0;
double netOutput = 0;
double bias2_out = 0;
double delta1 = 0;
double delta2 = 0;
double delta3 = 0;
double delta4 = 0;
double delta5 = 0;
double bias = 1;
double val = 0;

vector<double> neuron1_out;
vector<double> neuron2_out;
vector<double> neuron3_out;
vector<double> neuron4_out;
vector<double> weightVals;
vector<double> bias1_out;
vector<double> topology;
vector<double> inputs;

neuron1_out.clear();
neuron2_out.clear();
neuron3_out.clear();
neuron4_out.clear();
weightVals.clear();
bias1_out.clear();
topology.clear();
inputs.clear();

topology.push_back(4);
topology.push_back(8);
topology.push_back(1);

inputs.push_back(1);
inputs.push_back(0);
inputs.push_back(0);
inputs.push_back(1);

ifstream read("weights.txt");

while(read >> val) {

    weightVals.push_back(val);

};

for(int i = 0; i < topology.at(1); ++i) {

    int j = i + topology.at(1);
    int k = j + topology.at(1);
    int m = k + topology.at(1);
    int n = m + topology.at(1);

    delta1 = (inputs.at(0) * weightVals.at(i));
    neuron1_out.push_back(delta1);

    delta2 = (inputs.at(1) * weightVals.at(j));
    neuron2_out.push_back(delta2);

    delta3 = (inputs.at(2) * weightVals.at(k));
    neuron3_out.push_back(delta3);

    delta4 = (inputs.at(3) * weightVals.at(m));
    neuron4_out.push_back(delta4);

    delta5 = (bias * weightVals.at(n));
    bias1_out.push_back(delta5);

}

for(unsigned i = 0; i < topology.at(1); ++i) {

    hidden_out += (weightVals.at(40 + i) * tanh(neuron1_out.at(i) + neuron2_out.at(i) +
                                            neuron3_out.at(i) + neuron4_out.at(i) + bias1_out.at(i)));

}

bias2_out = (bias * weightVals.back());

netOutput = tanh(hidden_out + bias2_out);

cout << "The output of this network is: " << netOutput << endl;

return 0;

}

一点背景:

** 这部分对于回答我的问题并不重要**

此文件是我打算加载到 Teensy 上的神经网络 (NN) 程序的大规模精简版。基本思想是原始神经网络程序太大太复杂,我们的 MC 无法及时处理。通过提取基于计算机的 NN 的权重并将其导入上述程序,我们有效地削减了 NN 中与训练和错误处理相关的不必要部分,并仅保留“前馈”功能。不幸的是,这只会将我的整体 .hex 文件大小从 ~ 1150kb 减少到 ~ 950kb。

【问题讨论】:

  • 看看去掉#include &lt;iostream&gt;#include &lt;fstream&gt;,输出使用printf,文件读取使用fscanf是否有显着效果。
  • 您是否检查过生成的二进制文件的大小?看看地图文件,你可能会感到惊讶。试想一下:您使用了 STL 的功能,众所周知,这会使您的代码膨胀。
  • 没有名为“teensy”的微控制器,有些主板显然带有 MK20DX256VMC7,它是具有 256kb 闪存的飞思卡尔 ARM Cortex M4。是的,它是一个微控制器,而不是 PC。

标签: c++ optimization embedded hex neural-network


【解决方案1】:

HEX 文件的大小大约是它所代表的实际程序大小的 3 倍。

我猜大部分是浮点仿真库和 C++ 支持。您可以查看地图文件以了解占用空间的内容。

【讨论】:

    【解决方案2】:

    首先,要了解 hex 文件格式是二进制图像的 ascii 文本表示。每个十六进制记录包含每个二进制字节两个字符,加上记录类型、位置、长度和校验和数据;因此,实际的二进制图像大小将小于十六进制文件大小的一半。

    您的工具链将创建(或至少可以选择创建)一个链接器映射文件,该文件将显示实际大小和构成图像的所有组件。

    源文件大小不是程序大小的指标。在您的情况下,您包含了 STL 和 iostream 库代码,这些代码非常消耗内存,最好避免在 vert 受限目标上使用。

    【讨论】:

      【解决方案3】:

      尝试使用 GCC 为 Cortex-M3 编译此代码(来自https://launchpad.net/gcc-arm-embedded 的最新版本)

      因为在裸机系统中我不支持 iostream 和 filestream,所以我注释掉了 ifstream readcout &lt;&lt; ...

      编译后的代码大约需要 9.5kbytes(十六进制文件大小 - 36k)。

      尝试删除ifstream(您的板上是否有功能齐全的文件系统?)。例如,从静态 const 数组中读取值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-19
        • 2012-09-23
        • 2020-03-20
        • 2010-10-11
        • 1970-01-01
        • 1970-01-01
        • 2020-10-25
        • 2011-08-06
        相关资源
        最近更新 更多