Compare commits

...

3 Commits

Author SHA1 Message Date
7d2ea63108 Create remap_cores.py 2024-07-04 09:21:33 +02:00
e610acfc8f Faster --stats 2024-07-04 09:20:54 +02:00
dee9f37a17 Update miss_topology 2024-07-04 09:20:27 +02:00
5 changed files with 186 additions and 63 deletions

View File

@ -163,7 +163,8 @@ columns = [
("helper_core_fixed", "helper_core", "core"), ("helper_core_fixed", "helper_core", "core"),
("helper_ht", "helper_core", "hthread"), ("helper_ht", "helper_core", "hthread"),
] ]
for (col, icol, key) in columns: if not args.stats:
for (col, icol, key) in columns:
df[col] = df[icol].apply(remap_core(key)) df[col] = df[icol].apply(remap_core(key))
print_timed(f"Column {col} added") print_timed(f"Column {col} added")
@ -244,7 +245,7 @@ def export_stats_csv():
""" """
Compute the statistic for 1 helper core/main core/slice/column Compute the statistic for 1 helper core/main core/slice/column
- median : default, not influenced by errors - median : default, not influenced by errors
- average : better accuracy when observing floor steps in the results - average : better precision when observing floor steps in the results
""" """
# return wq.median(x["time"], x[key]) # return wq.median(x["time"], x[key])
return np.average(x[key], weights=x["time"]) return np.average(x[key], weights=x["time"])

View File

@ -177,44 +177,76 @@ num_core = len(stats["main_core_fixed"].unique())/2
def ring_distance(x0, x1): def ring_distance(x0, x1):
""" """
return (a, b) where `a` is the core distance and `b` the larger "ring step" return (a, b) where `a` is the core distance and `b` the larger "ring step"
it is possible that going from 0->7 costs one more than 3->4
""" """
dist = abs(x0-x1) dist = abs(x0-x1)
if x0 // (num_core/2) != x1 // (num_core/2): if x0 // (num_core/2) != x1 // (num_core/2):
return min(num_core-1-dist, dist-1), 1 # côté du coeur différent
return min((num_core-1-dist, 2), (dist-1, 1))
else: else:
return dist, 0 return dist, 0
def slice_msg_distance(x1, x0): def slice_msg_distance(source, dest):
""" """
Si l'expéditeur est à l'extrémité d'une des lignes, il envoie toujours dans le même sens Si l'expéditeur est à l'extrémité d'une des lignes, il envoie toujours dans le même sens
(vers toute sa ligne d'abord), sinon, il prend le chemin le plus court (vers toute sa ligne d'abord), sinon, il prend le chemin le plus court
le bonus correspond au fait que 0->7 puisse coûter 1 de plus que 3->4
""" """
dist = abs(x0-x1) dist = abs(source-dest)
if x0 == 3: if source // (num_core/2) == dest // (num_core/2):
dist = (x0-x1+8)%8 return (dist, 0)
elif x0 == 4:
dist = (x1-x0+8)%8
if x0 in [0, 3, 4, 7]: # Pour aller de l'autre côté
if dist > 3: up, down = (num_core-1-dist, 2), (dist-1, 1)
return dist, 1 if source in [0, 7]:
return dist, 0 return down
if source in [3, 4] or source in [2, 5]:
return up
if source in [1, 6]:
return min(up, down)
return ring_distance(x0, x1) raise IndexError
def ha_dist(core, is_QPI):
"""
distance to Home Agent
"""
if is_QPI:
if core < 4:
return core
return 7-core
def miss_topology(main_core, slice_group, C, h, H): if core < 4:
core, ring = slice_msg_distance(main_core, slice_group) return 3-core
return C + h * core + H*ring return core-4
def miss_topology_df(x, C, h, H): def cclockwise_ha_dist(core, is_QPI):
func = lambda x, C, h, H: miss_topology(x["main_core_fixed"], x["slice_group"], C, h, H) """
return x.apply(func, args=(C, h, H), axis=1) counter-clockwise distance to Home Agent
"""
if is_QPI:
return 7-core
if core < 4:
return 3-core
return 11-core
def miss_topology(main_core, slice_group, h, down_jump, top_jump, ini, ha_h):
core, ring = slice_msg_distance(slice_group, main_core%8)
side_jump = 0
side_jump += top_jump if ring == 2 else 0
side_jump += down_jump if ring == 1 else 0
return (cclockwise_ha_dist(slice_group, False)//2)*ha_h+h*core + side_jump + ini
def miss_topology_df(x, h, down_jump, top_jump, ini, ha_h):
func = lambda x, h, down_jump, top_jump, ini, ha_h: miss_topology(x["main_core_fixed"], x["slice_group"], h, down_jump, top_jump, ini, ha_h)
return x.apply(func, args=(h, down_jump, top_jump, ini, ha_h), axis=1)
def remote_hit_topology(main_core, helper_core, slice_group, C, h, H): def remote_hit_topology(main_core, helper_core, slice_group, C, h, H):
core0, ring0 = slice_msg_distance(main_core, slice_group) core0, ring0, _ = slice_msg_distance(main_core, slice_group)
core1, ring1 = slice_msg_distance(helper_core, slice_group) core1, ring1, _ = slice_msg_distance(helper_core, slice_group)
return C + h*(core0+core1) + H*(ring0+ring1) return C + h*(core0+core1) + H*(ring0+ring1)
def remote_hit_topology_df(x, C, h, H): def remote_hit_topology_df(x, C, h, H):
@ -223,7 +255,7 @@ def remote_hit_topology_df(x, C, h, H):
def do_predictions(df): def do_predictions(df):
def plot_predicted_topo(col, row, x_ax, target, pred): def plot_predicted_topo(col, row, x_ax, target, pred, df=df):
title_letter = { title_letter = {
"main_core_fixed": "A", "main_core_fixed": "A",
"helper_core_fixed": "V", "helper_core_fixed": "V",
@ -238,14 +270,54 @@ def do_predictions(df):
df = df[(df["main_socket"] == 0) & (df["helper_socket"] == 0)] values = []
main_socket, helper_socket = 0, 0
dfc = df[(df["main_socket"] == main_socket) & (df["helper_socket"] == helper_socket)]
cores = sorted(list(dfc["main_core_fixed"].unique()))
slices = sorted(list(dfc["slice_group"].unique()))
res_miss = optimize.curve_fit( res_miss = optimize.curve_fit(
miss_topology_df, df[["main_core_fixed", "slice_group"]], df["clflush_miss_n"] miss_topology_df, dfc[["main_core_fixed", "slice_group"]], dfc["clflush_miss_n"]
) )
print("Miss topology:") print("Miss topology:")
print(res_miss) print(res_miss)
values.append(res_miss[0])
dfc["predicted_miss"] = miss_topology_df(dfc, *(res_miss[0]))
plot_predicted_topo("slice_group", None, "main_core_fixed", "clflush_miss_n", "predicted_miss", df=dfc)
plot_predicted_topo("main_core_fixed", None, "slice_group", "clflush_miss_n", "predicted_miss", df=dfc)
for slice_ in slices:
dfc = df[(df["slice_group"] == slice_) & (df["main_socket"] == main_socket) & (df["helper_socket"] == helper_socket)]
res_miss = optimize.curve_fit(
miss_topology_df, dfc[["main_core_fixed", "slice_group"]], dfc["clflush_miss_n"]
)
values.append(res_miss[0])
dfc[f"predicted_miss_{slice_}"] = miss_topology_df(dfc, *(res_miss[0]))
plot_predicted_topo("slice_group", None, "main_core_fixed", "clflush_miss_n", f"predicted_miss_{slice_}", df=dfc)
print(list(values[0]))
print()
for i in values[1:]:
print(list(i))
values = []
for core in cores:
dfc = df[(df["main_core_fixed"] == core) & (df["main_socket"] == main_socket) & (df["helper_socket"] == helper_socket)]
res_miss = optimize.curve_fit(
miss_topology_df, dfc[["main_core_fixed", "slice_group"]], dfc["clflush_miss_n"]
)
values.append(res_miss[0])
dfc[f"predicted_miss_core{core}"] = miss_topology_df(dfc, *(res_miss[0]))
plot_predicted_topo("main_core_fixed", None, "slice_group", "clflush_miss_n", f"predicted_miss_core{core}", df=dfc)
for i in values:
print(list(i))
return
res_remote_hit = optimize.curve_fit( res_remote_hit = optimize.curve_fit(
remote_hit_topology_df, df[["main_core_fixed", "helper_core_fixed", "slice_group"]], df["clflush_remote_hit"] remote_hit_topology_df, df[["main_core_fixed", "helper_core_fixed", "slice_group"]], df["clflush_remote_hit"]
) )
@ -253,13 +325,24 @@ def do_predictions(df):
print(res_remote_hit) print(res_remote_hit)
df["predicted_miss"] = miss_topology_df(df, *(res_miss[0]))
plot_predicted_topo("slice_group", None, "main_core_fixed", "clflush_miss_n", "predicted_miss")
plot_predicted_topo("main_core_fixed", None, "slice_group", "clflush_miss_n", "predicted_miss")
df["predicted_remote_hit"] = remote_hit_topology_df(df, *(res_remote_hit[0])) df["diff_miss"] = df["clflush_miss_n"] - df["predicted_miss"]
plot_predicted_topo("slice_group", "helper_core_fixed", "main_core_fixed", "clflush_remote_hit", "predicted_remote_hit") facet_grid(
plot_predicted_topo("main_core_fixed", "helper_core_fixed", "slice_group", "clflush_remote_hit", "predicted_remote_hit") df, None, "main_core_fixed", "slice_group",
title=f"predicted_miss_diff_facet_slice.png",
shown=["diff_miss"],
separate_hthreads=True
)
facet_grid(
df, None, "slice_group", "main_core_fixed",
title=f"predicted_miss_diff_facet_main.png",
shown=["diff_miss"],
separate_hthreads=True
)
# df["predicted_remote_hit"] = remote_hit_topology_df(df, *(res_remote_hit[0]))
# plot_predicted_topo("slice_group", "helper_core_fixed", "main_core_fixed", "clflush_remote_hit", "predicted_remote_hit")
# plot_predicted_topo("main_core_fixed", "helper_core_fixed", "slice_group", "clflush_remote_hit", "predicted_remote_hit")
@ -315,30 +398,34 @@ def facet_grid(
**kwargs **kwargs
) )
else: else:
grid.map(draw_fn, third, el, color=colors[i % len(colors)]) grid.map(draw_fn, third, el, color=colors[i % len(colors)], marker='+')
if title is not None: if title is not None:
plot(title, g=grid) plot(title, g=grid)
return grid return grid
def all_facets(df, pre="", post="", *args, **kwargs): def all_facets(df, pre="", post="", no_helper=False, *args, **kwargs):
""" """
df : panda dataframe df : panda dataframe
pre, post: strings to add before and after the filename pre, post: strings to add before and after the filename
""" """
helper = None if no_helper else "helper_core_fixed"
facet_grid( facet_grid(
df, "helper_core_fixed", "main_core_fixed", "slice_group", df, helper, "main_core_fixed", "slice_group",
title=f"{pre}facet_slice{post}.png", *args, **kwargs title=f"{pre}facet_slice{post}.png", *args, **kwargs,
separate_hthreads=False
) )
facet_grid( facet_grid(
df, "helper_core_fixed", "slice_group", "main_core_fixed", df, helper, "slice_group", "main_core_fixed",
title=f"{pre}facet_main{post}.png", *args, **kwargs title=f"{pre}facet_main{post}.png", *args, **kwargs,
separate_hthreads=False
) )
facet_grid( facet_grid(
df, "main_core_fixed", "slice_group", "helper_core_fixed", df, "main_core_fixed", "slice_group", "helper_core_fixed",
title=f"{pre}facet_helper{post}.png", *args, **kwargs title=f"{pre}facet_helper{post}.png", *args, **kwargs,
separate_hthreads=False
) )
@ -369,6 +456,7 @@ def do_facet(main: int, helper: int, line: bool, metrics: str):
post=f"_m{main}h{helper}", post=f"_m{main}h{helper}",
shown=shown, shown=shown,
colors=colors, colors=colors,
no_helper=True,
draw_fn=sns.lineplot if line else sns.scatterplot draw_fn=sns.lineplot if line else sns.scatterplot
) )
@ -376,19 +464,28 @@ def do_facet(main: int, helper: int, line: bool, metrics: str):
if args.rslice: if args.rslice:
rslice() rslice()
# do_predictions(stats) do_predictions(stats)
# all_facets(stats, shown=["clflush_remote_hit"], colors=["r"]) #all_facets(stats, shown=["clflush_remote_hit"], colors=["r"], pre="hit")
#all_facets(stats, shown=["clflush_miss_n"], colors=["b"], pre="miss")
#df=stats
#for m, h, s in itertools.product((0, 1), (0, 1), df["slice_group"].unique()):
# dfc = df[(df["main_socket"] == m) & (df["main_core_fixed"]%8é == s) & (df["helper_socket"] == h)]
#
# grid = sns.FacetGrid(dfc, row=None, col=None)
# grid.map(sns.scatterplot, "slice_group", "clflush_miss_n", marker="+")
#
# plot(f"miss_m{m}h{h}m{s}", g=grid)
#with Pool(8) as pool:
with Pool(8) as pool: # pool.starmap(
pool.starmap( # do_facet,
do_facet, # itertools.product(
itertools.product( # stats["main_socket"].unique(),
stats["main_socket"].unique(), # stats["helper_socket"].unique(),
stats["helper_socket"].unique(), # (False, ),
(True, False), # ("hit", "miss")
("hit", "miss") # )
) # )
)

View File

@ -0,0 +1,25 @@
import sys
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <input.csv> <mapping>")
sys.exit(1)
input_file = sys.argv[1]
mapping_file = sys.argv[2]
mapping = []
with open(mapping_file, "r") as f:
for i in f.read().split("\n"):
if i != "":
mapping.append(int(i))
with open(input_file, "r") as f:
for line in f.read().split("\n"):
if line == "" or "core" in line:
print(line)
continue
sock, core, ht = map(int, line.split(","))
core = mapping[core]
print(f"{sock},{core},{ht}")