Add a sample program to verify compiler optimisations.

This commit is contained in:
King_DuckZ 2020-06-10 18:15:51 +02:00
parent af7fe9f1fa
commit 31546e83c6
3 changed files with 124 additions and 0 deletions

51
asm_test/README.md Normal file
View file

@ -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.

70
asm_test/asm_test.cpp Normal file
View file

@ -0,0 +1,70 @@
//#define USE_STD_ARRAY
//#define WITH_VWR
#if defined(WITH_VWR)
# include <vectorwrapper/vectorops.hpp>
#endif
#if defined(USE_STD_ARRAY)
# include <array>
#endif
#include <cstddef>
#include <iostream>
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<std::array<float, 3>> {
enum { dimensions = 3 };
typedef float scalar_type;
typedef std::array<float, 3> vector_type;
static scalar_type& get_at (std::size_t idx, vector_type& v) {
return v[idx];
}
};
#else
template <> struct VectorWrapperInfo<MyVecStruct> {
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<std::array<float, 3>, 3> vec3;
#else
typedef vwr::Vec<MyVecStruct, 3> 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<float, 3> 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<int>(sum);
}

View file

@ -0,0 +1,3 @@
1
2
3