There is no magic number. The inline comments tell exactly where and how many paddings are.
TimeDistance has 4 fields, bytes count to 26, followed by 6 un-named paddings. Then, 36 more bytes followed by 4 un-named paddings, and 70 more bytes to finished the copy: 26+36+70=132.
To figure out exactly where and how many paddings,
1) define a field equal operator,
2) make a byte change. If equal remains, this byte is a padding byte.
Do for ENVIRONMENT64:
There are 12 structal paddings inside Data struct of Group 1
00000000000000000000000000111111000...
Do for ENVIRONMENT32:
There are 4 structal paddings inside Data struct of Group 1
00000000000000000000000000110000000...
1 2 3 4 5 6 7
|
static_assert(sizeof(Data) == 132, "You forgot to disable padding!");
#ifdef ENVIRONMENT64
static_assert(sizeof(Data1) == 144, "Enable padding");
#else
static_assert(sizeof(Data1) == 136, "Enable padding");
#endif
| |
Otherwise, the code cannot compile.
1 2 3 4 5 6 7 8 9 10
|
void solution2(const char *source, Data1 &d) {
#ifdef ENVIRONMENT64
memcpy((char *)(&d), source, 26);
memcpy((char *)(&d.lat), source+26, 36);
memcpy((char *)(&d.vehicle.roll), source+26+36, 70);
#else
memcpy((char *)(&d), source, 26);
memcpy((char *)(&d.lat), source+26, 132-26);
#endif
}
| |
GPS have pretty stable data structure. For example, from POS TNG3 to POS LV5 release, about 10 years passed, quality improved a lot, but the data structure remains unchanged.
The code will be finally run in an embedded system. Before I reach the hardware, here is an early result on two development machines:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
size_t N = 9999999999;
{
Timeit timeit;
double sum = 0;
for (size_t i = 0; i < N; ++ i) {
Data d;
solution1(source, d);
sum += d.alt;
}
cout << "1: alt: " << sum/N << endl;
}
{
Timeit timeit;
double sum = 0;
for (size_t i = 0; i < N; ++ i) {
Data1 d;
solution2(source, d);
sum += d.alt;
}
cout << "2: alt: " << sum/N << endl;
}
{
Timeit timeit;
double sum = 0;
for (size_t i = 0; i < N; ++ i) {
Data d;
solution3(source, d);
sum += d.alt;
}
cout << "3: alt: " << sum/N << endl;
}
{
Timeit timeit;
double sum = 0;
for (size_t i = 0; i < N; ++ i) {
Data1 d;
solution4(source, d);
sum += d.alt;
}
cout << "4: alt: " << sum/N << endl;
}
| |
1 2 3 4 5 6 7 8 9 10 11
|
Windows(64bit)
1: alt: -86.9947818556557 Time elapsed 8125
2: alt: -86.9947818556557 Time elapsed 8123
3: alt: -86.9947818556557 Time elapsed 8118
4: alt: -86.9947818556557 Time elapsed 8122
Fedora (32bit)
1: alt: -86.99479215760162276 Time elapsed 18222
2: alt: -86.99479215760162276 Time elapsed 15894
3: alt: -86.99479215760162276 Time elapsed 10429
4: alt: -86.99479215760162276 Time elapsed 10435
| |
About GPS accuracy: 10 centimeter results in 0.000001 degree at latitude 40.47028.
so lat,lng,alt are in double precision, but IMU data can be float.