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