Add a sample program to verify compiler optimisations.
This commit is contained in:
parent
af7fe9f1fa
commit
31546e83c6
3 changed files with 124 additions and 0 deletions
51
asm_test/README.md
Normal file
51
asm_test/README.md
Normal 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
70
asm_test/asm_test.cpp
Normal 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);
|
||||||
|
}
|
3
asm_test/sample_input.txt
Normal file
3
asm_test/sample_input.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
Loading…
Reference in a new issue