updated create csv and updated plots
This commit is contained in:
committed by
[Quy Anh] «Elliot» Nguyen
parent
daf75faaf3
commit
ac9ef23559
+84
-30
@@ -81,13 +81,14 @@ base = get("variant_baseline")
|
||||
# plot 1: the two precision tracks (this is the main results plot)
|
||||
# double tops out ~7, float goes to 24. also shows the avx2-float stuff already does most of the work
|
||||
tracks = [
|
||||
("variant_inlining_7_SoA_AVX2", "double, AVX2", "#9bbbe0", "--"),
|
||||
("variant_baseline", "baseline (scalar)", "#7a7a7a", "-"),
|
||||
("variant_AVX512_1", "double, AVX-512 ", "#4f86d6", "-"),
|
||||
("variant_inlining_7_SoA_AVX2", "double, AVX-256", "#9bbbe0", "--"),
|
||||
("variant_inlining_8_SoA_AVX512_polyexp_moreavx", "double, AVX-512 + polyexp", "#2f5d9e", "-"),
|
||||
("variant_float_inlining_SoA_AVX2_polyexp", "float, AVX2 + polyexp", "#e58aa6", "--"),
|
||||
("variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt", "float, AVX2 + polyexp + rsqrt", "#d05a82", "--"),
|
||||
("variant_float_inlining_SoA_AVX2_polyexp", "float, AVX-256 + polyexp", "#e58aa6", "--"),
|
||||
("variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt", "float, AVX-256 + polyexp + rsqrt", "#d05a82", "--"),
|
||||
("variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt", "float, AVX-512 + rsqrt + ILP (best)", maroon, "-"),
|
||||
]
|
||||
|
||||
fig, ax = plt.subplots(figsize=(9,4.7))
|
||||
ends = []
|
||||
for v,lab,c,ls in tracks:
|
||||
@@ -144,43 +145,53 @@ plt.tight_layout()
|
||||
plt.savefig("analysis/fig_ladder.png", dpi=170, bbox_inches="tight")
|
||||
|
||||
|
||||
# plot3 roofline
|
||||
# every variant has the same I at a given n (W and Q dont change between variants), so the
|
||||
# points just stack vertically. we're miles to the right of the ridge -> compute bound.
|
||||
fig,ax = plt.subplots(figsize=(9,4.7))
|
||||
bw = 60 # bytes/cycle, ~120 GB/s lpddr5x / 2GHz. rough
|
||||
xx = np.logspace(-1, 3.6, 200)
|
||||
ax.plot(xx, np.minimum(bw*xx, PEAK_F), color="#cccccc", lw=1.2)
|
||||
# plot 3: roofline (n = 5000). same 7 variants as fig_tracks, same colors, inline labels.
|
||||
# float variants move HALF the bytes -> 2x the operational intensity of the double ones
|
||||
# (I_double ≈ 2.8k, I_float ≈ 5.6k), so each point uses its OWN I.
|
||||
# memory roof from a measured single-thread read: sysbench 37618 MiB/s -> ~19.7 bytes/cycle @ 2 GHz.
|
||||
def getI(v, n=5000):
|
||||
return df[(df.variant==v) & (df.n==n)]["I"].values[0]
|
||||
bw = 37618.01 * 1024**2 / 2e9 # MiB/s -> bytes/cycle at 2 GHz (≈ 19.72)
|
||||
|
||||
for pk,t in [(SCALAR,"scalar (4)"),(PEAK_D,"double (16)"),(PEAK_F,"float (32)")]:
|
||||
ax.axhline(pk, ls="--", color="#999", lw=1.1)
|
||||
ax.text(0.11, pk*1.04, t+" peak", fontsize=9.5, color="#888")
|
||||
|
||||
I5000 = df[(df.variant=="variant_baseline") & (df.n==5000)]["I"].values[0]
|
||||
pts = [
|
||||
("variant_baseline", "#7a7a7a"),
|
||||
("variant_AVX512_1", "#2f9e8f"),
|
||||
("variant_inlining_8_SoA_AVX512_polyexp_moreavx", "#e08a1e"),
|
||||
("variant_float_inlining_SoA_AVX512_polyexp_moreavx", "#c0436a"),
|
||||
("variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt", maroon),
|
||||
# (variant, label, color, group) group "d" = double column, "f" = float column
|
||||
roof = [
|
||||
("variant_baseline", "baseline (scalar)", "#7a7a7a", "d"),
|
||||
("variant_inlining_7_SoA_AVX2", "double, AVX-256", "#9bbbe0", "d"),
|
||||
("variant_AVX512_1", "double, AVX-512 ", "#4f86d6", "d"),
|
||||
("variant_inlining_8_SoA_AVX512_polyexp_moreavx", "double, AVX-512 + polyexp", "#2f5d9e", "d"),
|
||||
("variant_float_inlining_SoA_AVX2_polyexp", "float, AVX-256 + polyexp", "#e58aa6", "f"),
|
||||
("variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt", "float, AVX2 + polyexp + rsqrt", "#d05a82", "f"),
|
||||
("variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt", "float, AVX-512 + rsqrt + ILP (best)", maroon, "f"),
|
||||
]
|
||||
for v,c in pts:
|
||||
ax.plot(I5000, get(v), "o", ms=9, color=c, mec="white", mew=1)
|
||||
LABX = {"d": 2400, "f": 4900} # label right-edge sits just left of each column
|
||||
|
||||
fig, ax = plt.subplots(figsize=(9.5,5.0))
|
||||
xx = np.logspace(-1, 4.2, 200)
|
||||
ax.plot(xx, np.minimum(bw*xx, PEAK_F), color="#bbbbbb", lw=1.4)
|
||||
ax.text(0.115, 0.85, "mem roof: DRAM read ≈ 37.6 GiB/s (≈19.7 B/cycle)", fontsize=8.3, color="#9a9a9a", ha="left")
|
||||
|
||||
ax.text(I5000, 1.3, "n=5000", fontsize=10, color="#555")
|
||||
for pk,t in [(SCALAR,"scalar (4)"), (PEAK_D,"double (16)"), (PEAK_F,"float (32)")]:
|
||||
ax.axhline(pk, ls="--", color="#aaaaaa", lw=1.0)
|
||||
ax.text(0.11, pk*1.05, t+" peak", fontsize=9, color="#888")
|
||||
|
||||
for v,lab,c,grp in roof:
|
||||
x,y = getI(v), get(v)
|
||||
ax.plot(x, y, "o", ms=10, color=c, mec="white", mew=1.4, zorder=5)
|
||||
t = ax.text(LABX[grp], y, lab, color=c, fontsize=8, fontweight="bold", ha="right", va="center", zorder=6)
|
||||
t.set_path_effects([pe.withStroke(linewidth=2.5, foreground="white")])
|
||||
|
||||
ax.text(2812, 0.74, "I ≈ 2.8k", fontsize=8, color="#777", ha="center", va="top")
|
||||
ax.text(5625, 0.74, "I ≈ 5.6k", fontsize=8, color="#777", ha="center", va="top")
|
||||
|
||||
ax.set_xscale("log"); ax.set_yscale("log")
|
||||
ax.set_xlim(0.1, 6500); ax.set_ylim(0.7, 45)
|
||||
ax.set_xlim(0.1, 16000); ax.set_ylim(0.6, 46)
|
||||
ax.set_xlabel("operational intensity I [flops/byte]")
|
||||
ax.set_ylabel("performance [flops/cycle]")
|
||||
#ax.set_title("roofline: deeply compute-bound (I grows with n; work O(n^2), data O(n))", loc="left", fontsize=12)
|
||||
ax.grid(color="#ededed")
|
||||
ax.spines["top"].set_visible(False); ax.spines["right"].set_visible(False)
|
||||
plt.tight_layout()
|
||||
plt.savefig("analysis/fig_roofline.png", dpi=170, bbox_inches="tight")
|
||||
|
||||
|
||||
# plot 4: exp vs the polynomial approx (just to show its basically exact)
|
||||
x = np.linspace(-6, 0, 300)
|
||||
ex = np.exp(x)
|
||||
@@ -205,7 +216,7 @@ plt.savefig("analysis/fig_exp.png", dpi=170, bbox_inches="tight")
|
||||
# "above" or "below" -> alternate the crowded float labels above/below their line.
|
||||
milestones = [
|
||||
("variant_baseline", "baseline", "#7a7a7a", "-", None, "above"),
|
||||
("variant_cutoff_callsite", "baseline + cutoff (best scalar)", "#9e8f2f", "-", None, "below"),
|
||||
#("variant_cutoff_callsite", "baseline + cutoff (best scalar)", "#9e8f2f", "-", None, "below"),
|
||||
("variant_inlining_7_SoA_AVX2", "AVX2 (double)", "#3b6fb0", "--", None, "above"),
|
||||
("variant_inlining_7_SoA_AVX2_polyexp", "AVX2 + polyexp (double)", "#2f9e8f", "--", None, "below"),
|
||||
("variant_inlining_8_SoA_AVX512_polyexp_moreavx", "AVX-512 (double)", "#2f5d9e", "-", None, "below"),
|
||||
@@ -244,4 +255,47 @@ plt.savefig("analysis/fig_milestones.png", dpi=170, bbox_inches="tight")
|
||||
|
||||
|
||||
#plt.show()
|
||||
print("done")
|
||||
print("done")
|
||||
|
||||
# plot 6: wall-clock speedup over baseline (runtime, not performance).
|
||||
# the fair view for optimizations that change the flop count -- cutoff skips ~40% of the
|
||||
# inner loop, symmetry does half the pairs -- so flops/cycle misrepresents them. T_base /
|
||||
# T_variant compares time-to-solve the same n regardless of how many flops each one does.
|
||||
# curated to the milestones that carry the story + symmetry as the cautionary line.
|
||||
basec = df[df.variant == "variant_baseline"].set_index("n")["cycles"].to_dict()
|
||||
def speedline(v):
|
||||
s = df[df.variant == v].sort_values("n")
|
||||
ns = [n for n in s.n.values if n in basec] # baseline has no n=10000 run
|
||||
sp = [basec[n] / s[s.n == n]["cycles"].values[0] for n in ns]
|
||||
return np.array(ns, float), np.array(sp, float)
|
||||
|
||||
# (variant, label, color, linestyle, xpos|None, side)
|
||||
speed = [
|
||||
("variant_cutoff_callsite", "scalar + cutoff (approx)", "#9e8f2f", "-", 260, "above"),
|
||||
("variant_inlining_7_symmetry_2", "symmetry (half the pairs)", "#cf2b2b", "-", 320, "below"),
|
||||
("variant_inlining_7_SoA_AVX2", "double, AVX2", "#9bbbe0", "--", 650, "below"),
|
||||
("variant_inlining_8_SoA_AVX512_polyexp_moreavx", "double, AVX-512 + polyexp", "#2f5d9e", "-", 430, "above"),
|
||||
("variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt", "float, AVX2 + polyexp + rsqrt", "#d05a82", "--", 950, "below"),
|
||||
("variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt", "float, AVX-512 + rsqrt + ILP (best)", maroon, "-", 680, "above"),
|
||||
]
|
||||
fig, ax = plt.subplots(figsize=(9,4.7))
|
||||
ends = []
|
||||
for v,lab,c,ls,xpos,side in speed:
|
||||
x,y = speedline(v)
|
||||
if len(x) == 0:
|
||||
print("skip (not in csv):", v); continue
|
||||
ax.plot(x, y, ls, color=c, marker="o", ms=4, lw=2.4 if c==maroon else 1.8)
|
||||
ends.append((x, y, lab, c, xpos, side))
|
||||
ax.axhline(1, ls=":", color="#999", lw=1.3)
|
||||
ax.text(52, 1.03, "baseline (1x)", fontsize=9, color="#888")
|
||||
ax.set_xscale("log"); ax.set_yscale("log")
|
||||
ax.set_xticks([50,100,200,500,1000,2000,5000]); ax.set_xticklabels(["50","100","200","500","1k","2k","5k"])
|
||||
ax.set_yticks([1,2,5,10,20]); ax.set_yticklabels(["1x","2x","5x","10x","20x"])
|
||||
ax.set_xlim(46,7000); ax.set_ylim(0.8,28)
|
||||
ax.set_xlabel("number of pedestrians n")
|
||||
ax.set_ylabel("speedup over baseline (wall-clock cycles)")
|
||||
ax.grid(color="#e9e9e9")
|
||||
ax.spines["top"].set_visible(False); ax.spines["right"].set_visible(False)
|
||||
plt.tight_layout()
|
||||
label_lines_above(ax, ends, fontsize=7.5, dy_frac=0.02, halo=2)
|
||||
plt.savefig("analysis/fig_speedup.png", dpi=170, bbox_inches="tight")
|
||||
Reference in New Issue
Block a user