Skip to content

Commit 4076251

Browse files
authored
Merge pull request #952 from cppalliance/951
Bugfixes for Intel Benchmarks and update docs with complete results
2 parents 7b15b69 + 876eb43 commit 4076251

File tree

2 files changed

+81
-76
lines changed

2 files changed

+81
-76
lines changed

doc/modules/ROOT/pages/benchmarks.adoc

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ To run the benchmarks yourself, navigate to the test folder and define `BOOST_DE
2424
An example on Linux with b2: `../../../b2 cxxstd=20 toolset=gcc-13 define=BOOST_DECIMAL_RUN_BENCHMARKS benchmarks -a release`, or
2525
`../../../b2 cxxstd=20 toolset=gcc-13 define=BOOST_DECIMAL_RUN_BENCHMARKS=1,BOOST_DECIMAL_BENCHMARK_CHARCONV=1 benchmarks -a release` to also run the `<charconv>` benchmarks
2626

27+
To run the GCC benchmarks you can use the following command: `gcc benchmark_libdfp.c -O3 -std=c17` followed by: `./a.out`
28+
29+
To run the Intel benchmarks you will need both the https://www.intel.com/content/www/us/en/developer/tools/oneapi/overview.html[Intel Compiler], and the https://www.intel.com/content/www/us/en/developer/articles/tool/intel-decimal-floating-point-math-library.html[library].
30+
You can the use the following command: `icx benchmark_libbid.c -O3 $PATH_TO_LIBBID/libbid.a -std=c17` followed by: `./a.out`
31+
32+
NOTE: The Intel benchmarks can only be run on one of their supported architectures: IA-32, IA-64, and Intel x64
33+
2734
== Methodology
2835

2936
=== Comparisons
@@ -85,14 +92,14 @@ Intel Compiler:
8592
| 698,945
8693
| 4.856
8794
| Intel `Decimal32`
88-
| 2,023,493
89-
| 14.059
95+
| 2,411,294
96+
| 16.754
9097
| Intel `Decimal64`
91-
| 2,386,409
92-
| 16.581
98+
| 3,158,422
99+
| 21.945
93100
| Intel `Decimal128`
94-
| 3,203,050
95-
| 22.255
101+
| 3,389,883
102+
| 23.553
96103
|===
97104

98105
GCC:
@@ -165,14 +172,14 @@ Intel Compiler:
165172
| 1,367,004
166173
| 15.092
167174
| Intel `Decimal32`
168-
| 1,159,069
169-
| 12.796
175+
| 1,242,797
176+
| 13.721
170177
| Intel `Decimal64`
171-
| 1,248,111
172-
| 13.779
178+
| 1,689,585
179+
| 18.653
173180
| Intel `Decimal128`
174-
| 2,099,084
175-
| 23.174
181+
| 1,958,345
182+
| 21.620
176183
|===
177184

178185
GCC:
@@ -245,14 +252,14 @@ Intel Compiler:
245252
| 1,212,405
246253
| 16.564
247254
| Intel `Decimal32`
248-
| 1,275,562
249-
| 17.427
255+
| 1,922,108
256+
| 26.261
250257
| Intel `Decimal64`
251-
| 1,019,947
252-
| 13.935
258+
| 1,793,879
259+
| 24.509
253260
| Intel `Decimal128`
254-
| 2,162,490
255-
| 29.545
261+
| 2,397,372
262+
| 32.754
256263
|===
257264

258265
GCC:
@@ -325,15 +332,14 @@ Intel Compiler:
325332
| 5,959,977
326333
| 81.870
327334
| Intel `Decimal32`
328-
| 931,655
329-
| 12.798
335+
| 1,375,434
336+
| 18.894
330337
| Intel `Decimal64`
331-
| 963,464
332-
| 13.235
333-
// For unknown reasons this function segfaults
334-
//| Intel `Decimal128`
335-
//| 2,162,490
336-
//| 29.545
338+
| 2,052,278
339+
| 28.191
340+
| Intel `Decimal128`
341+
| 5,964,489
342+
| 81.932
337343
|===
338344

339345
GCC:
@@ -405,16 +411,15 @@ Intel Compiler:
405411
| `decimal_fast128_t`
406412
| 8,277,721
407413
| 79.750
408-
// For unknown reasons this function segfaults
409-
//| Intel `Decimal32`
410-
//| 931,655
411-
//| 12.798
412-
//| Intel `Decimal64`
413-
//| 963,464
414-
//| 13.235
415-
//| Intel `Decimal128`
416-
//| 2,162,490
417-
//| 29.545
414+
| Intel `Decimal32`
415+
| 1,561,213
416+
| 15.041
417+
| Intel `Decimal64`
418+
| 3,115,862
419+
| 30.019
420+
| Intel `Decimal128`
421+
| 7,474,712
422+
| 72.013
418423
|===
419424

420425
GCC:

test/benchmark_libbid.c

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
// https://www.boost.org/LICENSE_1_0.txt
44

55
#define _POSIX_C_SOURCE 199309L
6-
#define DECIMAL_GLOBAL_ROUNDING 1
7-
#define DECIMAL_GLOBAL_EXCEPTION_FLAGS 1
86

97
#include <stdio.h>
108
#include <stdlib.h>
@@ -23,6 +21,8 @@ typedef BID_UINT128 Decimal128;
2321
#define K 20000000
2422
#define N 5
2523

24+
uint32_t flag = 0;
25+
2626
uint32_t random_uint32(void)
2727
{
2828
uint32_t r = 0;
@@ -36,20 +36,20 @@ uint32_t random_uint32(void)
3636

3737
uint64_t random_uint64(void)
3838
{
39-
uint32_t r = 0;
39+
uint64_t r = 0;
4040
for (int i = 0; i < 4; i++)
4141
{
4242
r = (r << 16) | (rand() & 0xFFFF);
4343
}
44-
44+
4545
return r;
4646
}
4747

4848
__attribute__ ((noinline)) void generate_vector_32(Decimal32* buffer, size_t buffer_len)
4949
{
5050
for (size_t i = 0; i < buffer_len; ++i)
5151
{
52-
buffer[i] = bid32_from_uint32(random_uint32() % 100);
52+
buffer[i] = bid32_from_uint32(random_uint32(), BID_ROUNDING_DOWN, &flag);
5353
}
5454
}
5555

@@ -67,12 +67,12 @@ __attribute__ ((noinline)) void test_comparisons_32(Decimal32* data, const char*
6767
Decimal32 val1 = data[k];
6868
Decimal32 val2 = data[k + 1];
6969

70-
s += (size_t)bid32_quiet_less(val1, val2);
71-
s += (size_t)bid32_quiet_less_equal(val1, val2);
72-
s += (size_t)bid32_quiet_greater(val1, val2);
73-
s += (size_t)bid32_quiet_greater_equal(val1, val2);
74-
s += (size_t)bid32_quiet_equal(val1, val2);
75-
s += (size_t)bid32_quiet_not_equal(val1, val2);
70+
s += (size_t)bid32_quiet_less(val1, val2, &flag);
71+
s += (size_t)bid32_quiet_less_equal(val1, val2, &flag);
72+
s += (size_t)bid32_quiet_greater(val1, val2, &flag);
73+
s += (size_t)bid32_quiet_greater_equal(val1, val2, &flag);
74+
s += (size_t)bid32_quiet_equal(val1, val2, &flag);
75+
s += (size_t)bid32_quiet_not_equal(val1, val2, &flag);
7676
}
7777
}
7878

@@ -86,7 +86,7 @@ __attribute__ ((noinline)) void generate_vector_64(Decimal64* buffer, size_t buf
8686
{
8787
for (size_t i = 0; i < buffer_len; ++i)
8888
{
89-
buffer[i] = bid64_from_uint64(random_uint64() % 10000);
89+
buffer[i] = bid64_from_uint64(random_uint64(), BID_ROUNDING_DOWN, &flag);
9090
}
9191
}
9292

@@ -104,12 +104,12 @@ __attribute__ ((noinline)) void test_comparisons_64(Decimal64* data, const char*
104104
Decimal64 val1 = data[k];
105105
Decimal64 val2 = data[k + 1];
106106

107-
s += (size_t)bid64_quiet_less(val1, val2);
108-
s += (size_t)bid64_quiet_less_equal(val1, val2);
109-
s += (size_t)bid64_quiet_greater(val1, val2);
110-
s += (size_t)bid64_quiet_greater_equal(val1, val2);
111-
s += (size_t)bid64_quiet_equal(val1, val2);
112-
s += (size_t)bid64_quiet_not_equal(val1, val2);
107+
s += (size_t)bid64_quiet_less(val1, val2, &flag);
108+
s += (size_t)bid64_quiet_less_equal(val1, val2, &flag);
109+
s += (size_t)bid64_quiet_greater(val1, val2, &flag);
110+
s += (size_t)bid64_quiet_greater_equal(val1, val2, &flag);
111+
s += (size_t)bid64_quiet_equal(val1, val2, &flag);
112+
s += (size_t)bid64_quiet_not_equal(val1, val2, &flag);
113113
}
114114
}
115115

@@ -125,7 +125,7 @@ __attribute__ ((__noinline__)) void generate_vector_128(Decimal128* buffer, size
125125
size_t i = 0;
126126
while (i < buffer_len)
127127
{
128-
buffer[i] = bid128_from_uint64(random_uint64() % 100);
128+
buffer[i] = bid128_from_uint64(random_uint64());
129129
++i;
130130
}
131131
}
@@ -144,12 +144,12 @@ __attribute__ ((__noinline__)) void test_comparisons_128(Decimal128* data, const
144144
Decimal128 val1 = data[k];
145145
Decimal128 val2 = data[k + 1];
146146

147-
s += (size_t)bid128_quiet_less(val1, val2);
148-
s += (size_t)bid128_quiet_less_equal(val1, val2);
149-
s += (size_t)bid128_quiet_greater(val1, val2);
150-
s += (size_t)bid128_quiet_greater_equal(val1, val2);
151-
s += (size_t)bid128_quiet_equal(val1, val2);
152-
s += (size_t)bid128_quiet_not_equal(val1, val2);
147+
s += (size_t)bid128_quiet_less(val1, val2, &flag);
148+
s += (size_t)bid128_quiet_less_equal(val1, val2, &flag);
149+
s += (size_t)bid128_quiet_greater(val1, val2, &flag);
150+
s += (size_t)bid128_quiet_greater_equal(val1, val2, &flag);
151+
s += (size_t)bid128_quiet_equal(val1, val2, &flag);
152+
s += (size_t)bid128_quiet_not_equal(val1, val2, &flag);
153153
}
154154
}
155155

@@ -164,21 +164,21 @@ typedef Decimal32 (*operation_32)(Decimal32, Decimal32);
164164

165165
__attribute__ ((noinline)) Decimal32 add_32(Decimal32 a, Decimal32 b)
166166
{
167-
return bid32_add(a, b);
167+
return bid32_add(a, b, BID_ROUNDING_DOWN, &flag);
168168
}
169169
__attribute__ ((noinline)) Decimal32 sub_32(Decimal32 a, Decimal32 b)
170170
{
171-
return bid32_sub(a, b);
171+
return bid32_sub(a, b, BID_ROUNDING_DOWN, &flag);
172172
}
173173

174174
__attribute__ ((noinline)) Decimal32 mul_32(Decimal32 a, Decimal32 b)
175175
{
176-
return bid32_mul(a, b);
176+
return bid32_mul(a, b, BID_ROUNDING_DOWN, &flag);
177177
}
178178

179179
__attribute__ ((noinline)) Decimal32 div_32(Decimal32 a, Decimal32 b)
180180
{
181-
return bid32_div(a, b);
181+
return bid32_div(a, b, BID_ROUNDING_DOWN, &flag);
182182
}
183183

184184
__attribute__ ((noinline)) void test_two_element_operation_32(Decimal32* data, operation_32 op, const char* label, const char* op_label)
@@ -195,7 +195,7 @@ __attribute__ ((noinline)) void test_two_element_operation_32(Decimal32* data, o
195195
Decimal32 val1 = data[k];
196196
Decimal32 val2 = data[k + 1];
197197

198-
s += (size_t)bid32_to_int32_int(op(val1, val2));
198+
s += (size_t)bid32_to_int32_int(op(val1, val2), &flag);
199199
}
200200
}
201201

@@ -209,22 +209,22 @@ typedef Decimal64 (*operation_64)(Decimal64, Decimal64);
209209

210210
__attribute__ ((noinline)) Decimal64 add_64(Decimal64 a, Decimal64 b)
211211
{
212-
return bid64_add(a, b);
212+
return bid64_add(a, b, BID_ROUNDING_DOWN, &flag);
213213
}
214214

215215
__attribute__ ((noinline)) Decimal64 sub_64(Decimal64 a, Decimal64 b)
216216
{
217-
return bid64_sub(a, b);
217+
return bid64_sub(a, b, BID_ROUNDING_DOWN, &flag);
218218
}
219219

220220
__attribute__ ((noinline)) Decimal64 mul_64(Decimal64 a, Decimal64 b)
221221
{
222-
return bid64_mul(a, b);
222+
return bid64_mul(a, b, BID_ROUNDING_DOWN, &flag);
223223
}
224224

225225
__attribute__ ((noinline)) Decimal64 div_64(Decimal64 a, Decimal64 b)
226226
{
227-
return bid64_div(a, b);
227+
return bid64_div(a, b, BID_ROUNDING_DOWN, &flag);
228228
}
229229

230230
__attribute__ ((noinline)) void test_two_element_operation_64(Decimal64* data, operation_64 op, const char* label, const char* op_label)
@@ -241,7 +241,7 @@ __attribute__ ((noinline)) void test_two_element_operation_64(Decimal64* data, o
241241
Decimal64 val1 = data[k];
242242
Decimal64 val2 = data[k + 1];
243243

244-
s += (size_t)bid64_to_int64_int(op(val1, val2));
244+
s += (size_t)bid64_to_int64_int(op(val1, val2), &flag);
245245
}
246246
}
247247

@@ -256,22 +256,22 @@ typedef Decimal128 (*operation_128)(Decimal128, Decimal128);
256256

257257
__attribute__ ((__noinline__)) Decimal128 add_128(Decimal128 a, Decimal128 b)
258258
{
259-
return bid128_add(a, b);
259+
return bid128_add(a, b, BID_ROUNDING_DOWN, &flag);
260260
}
261261

262262
__attribute__ ((__noinline__)) Decimal128 sub_128(Decimal128 a, Decimal128 b)
263263
{
264-
return bid128_sub(a, b);
264+
return bid128_sub(a, b, BID_ROUNDING_DOWN, &flag);
265265
}
266266

267267
__attribute__ ((__noinline__)) Decimal128 mul_128(Decimal128 a, Decimal128 b)
268268
{
269-
return bid128_mul(a, b);
269+
return bid128_mul(a, b, BID_ROUNDING_DOWN, &flag);
270270
}
271271

272272
__attribute__ ((__noinline__)) Decimal128 div_128(Decimal128 a, Decimal128 b)
273273
{
274-
return bid128_div(a, b);
274+
return bid128_div(a, b, BID_ROUNDING_DOWN, &flag);
275275
}
276276

277277
__attribute__ ((__noinline__)) void test_two_element_operation_128(Decimal128* data, operation_128 op, const char* label, const char* op_label)
@@ -288,7 +288,7 @@ __attribute__ ((__noinline__)) void test_two_element_operation_128(Decimal128* d
288288
Decimal128 val1 = data[k];
289289
Decimal128 val2 = data[k + 1];
290290

291-
s += (size_t)bid128_to_int64_int(op(val1, val2));
291+
s += (size_t)bid128_to_int64_int(op(val1, val2), &flag);
292292
}
293293
}
294294

0 commit comments

Comments
 (0)