Skip to content

Commit 2b956a3

Browse files
committed
Add x86_32 linux data
1 parent f722922 commit 2b956a3

4 files changed

Lines changed: 165 additions & 2 deletions

File tree

doc/int128/u128_benchmarks.adoc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,29 @@ image::../u128_graphs/linux/s390x_relative_performance.png[s390x Relative Perfor
7272

7373
=== x86_32
7474

75-
NOTE: This platform has no hardware type so we compare relative to boost::mp::uint128_t
75+
NOTE: This platform has no hardware type so we compare relative to `boost::mp::uint128_t`
76+
77+
[cols="1,1,1"]
78+
|===
79+
| Operation | `uint128_t` | `boost::mp::uint128_t`
80+
81+
| Comparisons | 9000979 | 8722814
82+
| Addition | 898718 | 9912175
83+
| Subtraction | 778881 | 9773677
84+
| Multiplication | 1778273 | 8678420
85+
| Division | 8496503 | 18133965
86+
| Modulo | 9081442 | 11257837
87+
|===
88+
89+
////
90+
image::../u128_graphs/linux/x86_benchmarks.png[x86 Benchmark Results, width=100%]
91+
////
92+
93+
image::../u128_graphs/linux/x86_relative_performance.png[x86 Relative Performance, width=100%]
7694

7795
=== ARM32
7896

79-
NOTE: This platform has no hardware type so we compare relative to boost::mp::uint128_t
97+
NOTE: This platform has no hardware type so we compare relative to `boost::mp::uint128_t`
8098

8199
== Windows
82100

doc/plots_32bit.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import matplotlib.pyplot as plt
2+
import numpy as np
3+
import pandas as pd
4+
5+
# Linux S390x
6+
data = {
7+
'Operation': ['Comparisons', 'Addition', 'Subtraction', 'Multiplication', 'Division', 'Modulo'],
8+
'uint128_t': [9000979, 898718, 778881, 1778273, 8496503, 9081442],
9+
'boost::mp::uint128_t': [8722814, 9912175, 9773677, 8678420, 18133965, 11257837]
10+
}
11+
12+
df = pd.DataFrame(data)
13+
14+
# Function to determine color based on ranking
15+
def get_colors_by_rank(row):
16+
values = row[1:].values
17+
ranks = np.argsort(values) + 1
18+
colors = []
19+
for rank in ranks:
20+
if rank == 1:
21+
colors.append('#90EE90') # Light Green - Best
22+
elif rank == 2:
23+
colors.append('#FFFFE0') # Light Yellow - Second
24+
else:
25+
colors.append('#FFB6C1') # Light Red - Third
26+
return colors
27+
28+
# Create figure with subplots
29+
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10))
30+
31+
# Prepare data
32+
operations = df['Operation']
33+
x = np.arange(len(operations))
34+
width = 0.25
35+
36+
# Get implementation names
37+
implementations = df.columns[1:]
38+
39+
# Plot 1: Regular scale bar chart with color coding
40+
for i, (idx, row) in enumerate(df.iterrows()):
41+
colors = get_colors_by_rank(row)
42+
for j, impl in enumerate(implementations):
43+
ax1.bar(x[i] + (j-1)*width, row[impl], width,
44+
color=colors[j], edgecolor='black', linewidth=0.5,
45+
label=impl if i == 0 else "")
46+
47+
ax1.set_xlabel('Operations', fontsize=12)
48+
ax1.set_ylabel('Time (nanoseconds)', fontsize=12)
49+
ax1.set_title('GCC 14 - x86_32 Benchmark Results', fontsize=14, fontweight='bold')
50+
ax1.set_xticks(x)
51+
ax1.set_xticklabels(operations, rotation=45, ha='right')
52+
ax1.legend(loc='upper left')
53+
ax1.grid(axis='y', alpha=0.3)
54+
55+
# Add value labels on bars
56+
for i, (idx, row) in enumerate(df.iterrows()):
57+
for j, impl in enumerate(implementations):
58+
ax1.text(x[i] + (j-1)*width, row[impl], f'{row[impl]:,}',
59+
ha='center', va='bottom', fontsize=8, rotation=90)
60+
61+
# Plot 2: Log scale for better visualization
62+
for i, impl in enumerate(implementations):
63+
bars = ax2.bar(x + (i-1)*width, df[impl], width, label=impl, edgecolor='black', linewidth=0.5)
64+
65+
# Color each bar based on its rank within operation
66+
for j, bar in enumerate(bars):
67+
operation_values = df.iloc[j, 1:].values
68+
rank = np.argsort(operation_values).tolist().index(i) + 1
69+
if rank == 1:
70+
bar.set_facecolor('#90EE90')
71+
elif rank == 2:
72+
bar.set_facecolor('#FFFFE0')
73+
else:
74+
bar.set_facecolor('#FFB6C1')
75+
76+
ax2.set_xlabel('Operations', fontsize=12)
77+
ax2.set_ylabel('Time (nanoseconds) - Log Scale', fontsize=12)
78+
ax2.set_title('GCC 14 - x86_32 Benchmark Results (Log Scale)', fontsize=14, fontweight='bold')
79+
ax2.set_yscale('log')
80+
ax2.set_xticks(x)
81+
ax2.set_xticklabels(operations, rotation=45, ha='right')
82+
ax2.legend(loc='upper left')
83+
ax2.grid(axis='y', alpha=0.3, which='both')
84+
85+
plt.tight_layout()
86+
plt.savefig('x86_benchmarks.png', dpi=300, bbox_inches='tight')
87+
plt.show()
88+
89+
# Create a normalized performance chart
90+
fig3, ax3 = plt.subplots(figsize=(10, 6))
91+
92+
# Normalize data relative to boost::mp::uint128_t
93+
normalized_df = df.copy()
94+
for col in implementations:
95+
normalized_df[col] = df[col] / df['boost::mp::uint128_t']
96+
97+
# Plot normalized bars
98+
for i, impl in enumerate(implementations):
99+
if impl == 'boost::mp::uint128_t':
100+
continue # Skip since it's always 1.0
101+
bars = ax3.bar(x + (i-1.5)*width, normalized_df[impl], width,
102+
label=impl, edgecolor='black', linewidth=0.5)
103+
104+
# Add value labels
105+
for j, bar in enumerate(bars):
106+
height = bar.get_height()
107+
ax3.text(bar.get_x() + bar.get_width()/2., height,
108+
f'{height:.2f}x', ha='center', va='bottom', fontsize=9)
109+
110+
# Add reference line at 1.0
111+
ax3.axhline(y=1.0, color='red', linestyle='--', alpha=0.5, label='boost::mp::uint128_t baseline')
112+
113+
ax3.set_xlabel('Operations', fontsize=12)
114+
ax3.set_ylabel('Relative Performance (vs boost::mp::uint128_t)', fontsize=12)
115+
ax3.set_title('Relative Performance Comparison - x86_32', fontsize=14, fontweight='bold')
116+
ax3.set_xticks(x)
117+
ax3.set_xticklabels(operations, rotation=45, ha='right')
118+
ax3.legend()
119+
ax3.grid(axis='y', alpha=0.3)
120+
121+
# Add interpretation text
122+
ax3.text(0.02, 0.98, 'Lower is better', transform=ax3.transAxes,
123+
fontsize=10, verticalalignment='top', style='italic')
124+
125+
plt.tight_layout()
126+
plt.savefig('x86_relative_performance.png', dpi=300, bbox_inches='tight')
127+
plt.show()
128+
129+
# Generate summary statistics
130+
print("\nPerformance Summary (x64):")
131+
print("-" * 50)
132+
for impl in implementations:
133+
if impl == 'unsigned __int128':
134+
continue
135+
avg_ratio = normalized_df[impl].mean()
136+
print(f"{impl}: {avg_ratio:.2f}x average vs unsigned __int128")
137+
138+
print("\nBest performer by operation:")
139+
print("-" * 50)
140+
for i, op in enumerate(operations):
141+
row_data = df.iloc[i, 1:]
142+
best_impl = row_data.idxmin()
143+
best_time = row_data.min()
144+
print(f"{op}: {best_impl} ({best_time:,} ns)")
145+
355 KB
Loading
183 KB
Loading

0 commit comments

Comments
 (0)