From 31546e83c639ea321488ef10dd392cc7d6e564ec Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 10 Jun 2020 18:15:51 +0200 Subject: [PATCH] Add a sample program to verify compiler optimisations. --- asm_test/README.md | 51 ++++++++++++++++++++++++++++ asm_test/asm_test.cpp | 70 +++++++++++++++++++++++++++++++++++++++ asm_test/sample_input.txt | 3 ++ 3 files changed, 124 insertions(+) create mode 100644 asm_test/README.md create mode 100644 asm_test/asm_test.cpp create mode 100644 asm_test/sample_input.txt diff --git a/asm_test/README.md b/asm_test/README.md new file mode 100644 index 0000000..3f627e8 --- /dev/null +++ b/asm_test/README.md @@ -0,0 +1,51 @@ +# Checking the generated assembly # + +## The test ## +In `asm_test.cpp` you can find a small program that asks the user for three +input floats. The program will add these values together and use the int result +as its return value. You can compile different versions of this program so you +can compare the binaries: with or without VectorWrapper (`-DWITH_VWR`) and +using `std::array` (`-DUSE_STD_ARRAY`) (which will force VectorWrapper's +implementation to go through the `get_at()` implementation rather than using +the offset-based one) or using just a plain struct. Please have a look at the +source code, it's very short. + +## Compiling ## +You can compile four different binaries with the following commands: + +``` +g++ -o bin_vwr -O3 -std=gnu++14 asm_test.cpp -DWITH_VWR +g++ -o bin_vwr_array -O3 -std=gnu++14 asm_test.cpp -DWITH_VWR -DUSE_STD_ARRAY +g++ -o bin_plain -O3 -std=gnu++14 asm_test.cpp +g++ -o bin_plain_array -O3 -std=gnu++14 asm_test.cpp -DUSE_STD_ARRAY +``` + +* bin_vwr will use VectorWrapper and the custom struct (offset based accessors) +* bin_vwr_array will use VectorWrapper and `std::array` (`get_at()` method + based accessors) +* bin_plain will use the custom struct directly, without VectorWrapper +* bin_plain_array will use `std::array` directly, without VectorWrapper + +## Running ## +An input file is provided for convenience. You can run each binary like: + +``` +./bin_vwr < sample_input.txt +``` + +but of course using a debugger will give you some insight: + +``` +gdb ./bin_vwr +break main +layout asm +run < sample_input.txt +ni +... +``` + +## Results ## +On my system (amd64, g++ 8.3.0) this generates four identical binaries (you can +check their hash). Feel free to insert bad syntax in the code to make sure that +you're indeed compiling different ifdef branches. This is enough to say that at +least in this simple case VectorWrapper has no overhead. diff --git a/asm_test/asm_test.cpp b/asm_test/asm_test.cpp new file mode 100644 index 0000000..0cc7bcb --- /dev/null +++ b/asm_test/asm_test.cpp @@ -0,0 +1,70 @@ +//#define USE_STD_ARRAY +//#define WITH_VWR + +#if defined(WITH_VWR) +# include +#endif +#if defined(USE_STD_ARRAY) +# include +#endif +#include +#include + +namespace { +#if !defined(USE_STD_ARRAY) + struct MyVecStruct { + float x, y, z; + }; +#endif +} //unnamed namespace + +#if defined(WITH_VWR) +namespace vwr { +#if defined(USE_STD_ARRAY) + template <> struct VectorWrapperInfo> { + enum { dimensions = 3 }; + typedef float scalar_type; + typedef std::array vector_type; + static scalar_type& get_at (std::size_t idx, vector_type& v) { + return v[idx]; + } + }; +#else + template <> struct VectorWrapperInfo { + enum { dimensions = 3 }; + typedef float scalar_type; + typedef MyVecStruct vector_type; + enum { + offset_x = offsetof(MyVecStruct, x), + offset_y = offsetof(MyVecStruct, y), + offset_z = offsetof(MyVecStruct, z) + }; + }; +#endif +} //namespace vwr + +namespace { +#if defined(USE_STD_ARRAY) +typedef vwr::Vec, 3> vec3; +#else +typedef vwr::Vec vec3; +#endif +} //unnamed namespace +#endif + +int main() { +#if defined(WITH_VWR) + vec3 v; + std::cin >> v.x() >> v.y() >> v.z(); + const float sum = v.x() + v.y() + v.z(); +#elif defined(USE_STD_ARRAY) + std::array arr; + std::cin >> arr[0] >> arr[1] >> arr[2]; + const float sum = arr[0] + arr[1] + arr[2]; +#else + MyVecStruct v; + std::cin >> v.x >> v.y >> v.z; + const float sum = v.x + v.y + v.z; +#endif + return static_cast(sum); +} diff --git a/asm_test/sample_input.txt b/asm_test/sample_input.txt new file mode 100644 index 0000000..01e79c3 --- /dev/null +++ b/asm_test/sample_input.txt @@ -0,0 +1,3 @@ +1 +2 +3