|
| 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 | + |
0 commit comments