Sdbusplus/tight memory conditions

Wilfred Smith wilfredsmith at fb.com
Tue Sep 10 02:02:58 AEST 2019


Perhaps I’m doing it incorrectly…

target_compile_options( sizing.bin PUBLIC -Os -s)

…gets me a binary of 2,092,428. Saves 200K, but still north of 2 MB

Wilfred


On Sep 9, 2019, at 2:29 AM, Lei YU <mine260309 at gmail.com<mailto:mine260309 at gmail.com>> wrote:

Is the size before strip or after strip?
I suspect it's not stripped so you get a quite large size.

On Mon, Sep 9, 2019 at 4:34 PM Wilfred Smith <wilfredsmith at fb.com<mailto:wilfredsmith at fb.com>> wrote:

I’m having code size issues using the sdbusplus library. As I mentioned during the conference, I suspected it was a combinatorial expansion forced by the use of variant in a template. As a result, my “tiny” FRU dumping utility uses almost 3 MB on Tioga Pass and can only be stored on /tmp.. My sensor dumping utility, using the same structure by way of calling GetManagedObjects weighed in close to 9 MB, presumably because there are several loops that walk the structure, with even more templated function instantiation, which sux0rs when you only have a 32MB part. Even the best darn FRU utility in the world isn’t worth 25% of your available code space.

I hope I’m doing something wrong. The data structure is as recommended by Ed Tanous and I don’t see an obvious way to simplify the variant out of the structure. My current thoughts for proceeding are to (a) write my own task specific D-Bus library that isn’t as template-happy or (b) to re-implement with low-level D-Bus calls. Neither is particularly desirable since I would think all components should use the same library to access the D-Bus

My colleagues suspected I was statically linking the sdbusplus libraries, but as I’ll prove in the next section, the bloat doesn’t occur until I have code that touches the D-Bus response, and the code size scales directly with the number of variant types. That should be orthogonal to the penalty for linking statically, unless the template permutations are in the library itself, but libsdbusplus.so is a meager 18,140 bytes.Code size here is increasing by 80,345 bytes per additional variant type, which is 4x the size of the entire SO.

My presumption is that I’m off in the weeds, and someone will kindly guide me back to the main road.

Experiment 1: A minimal application
#include <iostream>

int main( int argc, char *argv ) {
std::cout << "Sizing app" << std::endl;
}

add_executable( sizing.bin source/sizing.cpp )
target_link_libraries( sizing.bin sdbusplus.so )
install( TARGETS sizing.bin )

104,828 bytes with or without link to sdbusplus.so

——————————————————————————————
Experiment 2: Add code to perform a GetManagedObjects. This increases the code payload substantially more than expected, but is still reasonable.

#include <iostream>
#include <sdbusplus/bus.hpp>


int main( int argc, char **argv ) {
std::cout << "Sizing app" << std::endl;
  auto bus = sdbusplus::bus::new_default_system();
  auto method = bus.new_method_call("xyz.openbmc_project.FruDevice",
                                       "/",
                                       "org.freedesktop.DBus.ObjectManager",
                                       "GetManagedObjects");
  auto response = bus.call(method);

}

add_executable( sizing.bin source/sizing.cpp )
target_link_libraries( sizing.bin sdbusplus.so
                                 systemd.so )
install( TARGETS sizing.bin )

255,212 bytes

——————————————————————————————————
Experiment  3: Added the structure to read the result into, and the size grows too 10x. Note that I’m not even doing anything with the result. It’s the interaction between the “read” and the storage type.

#include <iostream>
#include <sdbusplus/bus.hpp>
#include <boost/container/flat_map.hpp>

typedef sdbusplus::message::variant< std::string,
                                    bool,
                                    uint8_t,
                                    int16_t,
                                    uint16_t,
                                    int32_t,
                                    uint32_t,
                                    int64_t,
                                    uint64_t,
                                    double,
                                    std::vector<std::string>> AnyType;

typedef boost::container::flat_map< std::string, AnyType> AnyTypeMap;
typedef std::vector<std::pair<std::string, AnyTypeMap>> NamedArrayOfAnyTypeMaps;
typedef std::vector<std::pair<sdbusplus::message::object_path, NamedArrayOfAnyTypeMaps>> ArrayOfObjectPathsAndTieredAnyTypeMaps;


int main( int argc, char **argv ) {
  ArrayOfObjectPathsAndTieredAnyTypeMaps result;

std::cout << "Sizing app" << std::endl;
  auto bus = sdbusplus::bus::new_default_system();
  auto method = bus.new_method_call("xyz.openbmc_project.FruDevice",
                                       "/",
                                       "org.freedesktop.DBus.ObjectManager",
                                       "GetManagedObjects");
  auto response = bus.call(method);
  response.read( result );
}

2,274,736 bytes

—————————————————————————————————————
Experiment 4: If I reduce the number of permutations to 2, the code payload remains huge, but shrinks.

#include <iostream>
#include <sdbusplus/bus.hpp>
#include <boost/container/flat_map.hpp>

typedef sdbusplus::message::variant< std::string,
//                                     bool,
//                                     uint8_t,
//                                     int16_t,
//                                     uint16_t,
//                                     int32_t,
//                                     uint32_t,
//                                     int64_t,
//                                     uint64_t,
//                                     double,
                                    std::vector<std::string>> AnyType;

typedef boost::container::flat_map< std::string, AnyType> AnyTypeMap;
typedef std::vector<std::pair<std::string, AnyTypeMap>> NamedArrayOfAnyTypeMaps;
typedef std::vector<std::pair<sdbusplus::message::object_path, NamedArrayOfAnyTypeMaps>> ArrayOfObjectPathsAndTieredAnyTypeMaps;


int main( int argc, char **argv ) {
  ArrayOfObjectPathsAndTieredAnyTypeMaps result;

std::cout << "Sizing app" << std::endl;
  auto bus = sdbusplus::bus::new_default_system();
  auto method = bus.new_method_call("xyz.openbmc_project.FruDevice",
                                       "/",
                                       "org.freedesktop.DBus.ObjectManager",
                                       "GetManagedObjects");
  auto response = bus.call(method);
  response.read( result );
}

1,551,624 bytes

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/openbmc/attachments/20190909/5ed14410/attachment-0001.htm>


More information about the openbmc mailing list