0

My architecture is MicroBlaze, and I'm developing on the Xilinx ZCU102. The C++ version is 17. I built the code on Vitis 2022.2 version.

My original code had a .text section of only 60,000 bytes. After porting to C++, it increased to 180,000 bytes. I referred to this article and added the following two flags in CMake, but the effect was limited.

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")

I also added the following function, but it still didn't help.

extern "C" void __cxa_pure_virtual() { while(1); }

Next, I used this GitHub ELF analyzer to analyze it, and many functions appeared that I had never seen before porting c++ code.

$ elf-size-analyze -t mb- my.elf --rom -H
...

?                                                                    144.6 KiB   81.43
  d_print_comp_inner                                                  13.2 KiB    7.45
  _svfprintf_r                                                        10.9 KiB    6.15
  _dtoa_r                                                              6.8 KiB    3.84
  _vfiprintf_r                                                         5.5 KiB    3.08
  _svfiprintf_r                                                        4.8 KiB    2.70
  d_type                                                               3.2 KiB    1.78
  execute_cfa_program                                                  2.7 KiB    1.50
  d_expression_1                                                       2.4 KiB    1.35
  execute_stack_op                                                     2.4 KiB    1.34
  d_print_mod                                                          2.2 KiB    1.24
  _malloc_r                                                            2.2 KiB    1.23
  __divdi3                                                             2.0 KiB    1.10
  __udivdi3                                                            1.9 KiB    1.06
  d_special_name                                                       1.9 KiB    1.05
  __moddi3                                                             1.9 KiB    1.05
  __umoddi3                                                            1.8 KiB    1.00
  search_object                                                        1.8 KiB    0.99
  d_demangle_callback.constprop.0                                      1.7 KiB    0.94
  _realloc_r                                                           1.6 KiB    0.91
  d_unqualified_name                                                   1.6 KiB    0.88
  __sfvwrite_r                                                         1.3 KiB    0.74
  d_name                                                               1.2 KiB    0.70
  cplus_demangle_operators                                             1.1 KiB    0.64
  uw_frame_state_for                                                   1.1 KiB    0.64
  d_maybe_print_fold_expression                                        1.0 KiB    0.57
  uw_update_context_1                                                  1.0 KiB    0.57
  __malloc_av_                                                         1.0 KiB    0.57
  XpbrServExtTbl                                                       1.0 KiB    0.56


...

How can I reduce the size of my code? Thank you very much.

--- update ---

When I gradually commented out portions of my code to identify what caused a significant increase in the size of my .text section, I found that by removing the following code, my .text size reverted to 60000 bytes. However, I'm at a loss. Does C++ vector emplace_back do something specific?

template <typename T> using VEC = std::vector<T>;
using vecf = VEC<double>;

vecf delay_ns;
for (size_t i = 0; i < 10; i++) {
    delay_ns.emplace_back(2.0);
}
14
  • 1
    Are you compiling with -Os instead of some other optimization level? Commented May 17, 2024 at 2:56
  • Please include the compiler name and version in the question, and tag the compiler Commented May 17, 2024 at 2:59
  • Bit hard to guess without code. If your code uses new expressions at all (directly or indirectly) that can force the executable to still have code for exception handling (since operator new(), by default, still throws exceptions). This includes using standard containers since their default allocators use new expressions. Commented May 17, 2024 at 3:02
  • 1
    std::vector::emplace_back() resizes the vector which (e.g. if std::vector::capacity() is less than the new std::vector::size()) results in increasing the vector's capacity (number of elements it can contain without reallocation), which is done using the vector's allocator, which (by default) uses a new expression, which (by default) can throw an exception - which can force the executable to still have code for exception handling. Commented May 17, 2024 at 9:45
  • 1
    @n.m.couldbeanAI The default constructor for std::vector constructs an empty container with a default-constructed allocator - it's not unimaginable that the act of default-constructing a vector will not execute any new expression, so not (on its own) force the executable to have exception handling code, but a later call of emplace_back() of that vector might. Dunno - it's the OP who reported (previous comment) isolating his concern to a usage of emplace_back() and, since representative code isn't given, all we can do is speculate. Commented May 17, 2024 at 11:57

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.