Skip to content

Commit 372b4bb

Browse files
committed
support multiple L3 caches
1 parent df38a6c commit 372b4bb

File tree

1 file changed

+100
-48
lines changed

1 file changed

+100
-48
lines changed

core/utils/cpu.py

Lines changed: 100 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -387,21 +387,23 @@ def get_cache_info():
387387

388388

389389
def create_cpu_topology_visualization(p_cores, e_cores, cache_structure):
390+
plt.style.use('dark_background')
390391
fig, ax = plt.subplots(figsize=(20, 12))
391392
ax.set_aspect('equal')
392393

393-
# Colors
394-
p_core_color = '#ADD8E6' # Light blue
395-
e_core_color = '#90EE90' # Light green
396-
l1_color = '#FFB6C1' # Light pink
397-
l2_color = '#DDA0DD' # Plum
398-
l3_color = '#F0E68C' # Khaki
394+
# Lighter colors for dark theme
395+
p_core_color = '#2E6B9B' # Lighter blue
396+
e_core_color = '#2B7A44' # Lighter green
397+
l1_color = '#9B2E4F' # Lighter red
398+
l2_color = '#6B4488' # Lighter purple
399+
l3_color = '#8C8544' # Lighter gold
400+
text_color = '#E0E0E0' # Light gray for text
399401

400-
# Calculate basic dimensions
402+
# Rest of the dimensions remain the same
401403
core_width = 0.8
402404
core_height = 0.8
403-
core_gap = 0.4 # Gap between cores
404-
x_spacing = core_width + core_gap # = 1.2, distance from start of one core to start of next
405+
core_gap = 0.4
406+
x_spacing = core_width + core_gap
405407
y_spacing = 1.0
406408

407409
# Calculate layout dimensions
@@ -417,10 +419,10 @@ def create_cpu_topology_visualization(p_cores, e_cores, cache_structure):
417419
total_width = p_cores_width + ((e_cores_width + x_spacing) if e_cores else 0)
418420

419421
def format_size(size):
420-
if size >= 1024*1024:
421-
return f"{size/(1024*1024):.0f}M"
422+
if size >= 1024 * 1024:
423+
return f"{size / (1024 * 1024):.0f}M"
422424
elif size >= 1024:
423-
return f"{size/1024:.0f}K"
425+
return f"{size / 1024:.0f}K"
424426
return f"{size}B"
425427

426428
# Group cores by their L2 cache sharing
@@ -434,85 +436,135 @@ def format_size(size):
434436
for i, core in enumerate(sorted(p_cores)):
435437
x = (i % p_cores_per_row) * x_spacing
436438
y = (i // p_cores_per_row) * y_spacing * 3
437-
rect = patches.Rectangle((x, y), core_width, core_height, facecolor=p_core_color)
439+
rect = patches.Rectangle((x, y), core_width, core_height, facecolor=p_core_color, edgecolor='white',
440+
linewidth=0.5)
438441
ax.add_patch(rect)
439-
ax.text(x + core_width/2, y + core_height/2, f"P{core}", ha='center', va='center')
442+
ax.text(x + core_width / 2, y + core_height / 2, f"P{core}", ha='center', va='center', color=text_color)
440443

441-
# Find L1 caches for this core
442-
if i % 2 == 0: # For each pair of P-cores
443-
# Find L1 caches
444+
if i % 2 == 0:
444445
for cache in cache_structure:
445446
if cache['level'] == 1 and core in cache['cores']:
446447
if cache['type'] == 2: # L1i
447-
l1i = patches.Rectangle((x, y - 0.6), x_spacing * 2 - 0.4, 0.4, facecolor=l1_color)
448+
l1i = patches.Rectangle((x, y - 0.6), x_spacing * 2 - 0.4, 0.4,
449+
facecolor=l1_color, edgecolor='white', linewidth=0.5)
448450
ax.add_patch(l1i)
449451
ax.text(x + x_spacing - 0.2, y - 0.4, f"L1 (i) {format_size(cache['size'])}",
450-
ha='center', va='center', fontsize=8)
452+
ha='center', va='center', fontsize=8, color=text_color)
451453
elif cache['type'] == 1: # L1d
452-
l1d = patches.Rectangle((x, y - 1.0), x_spacing * 2 - 0.4, 0.4, facecolor=l1_color)
454+
l1d = patches.Rectangle((x, y - 1.0), x_spacing * 2 - 0.4, 0.4,
455+
facecolor=l1_color, edgecolor='white', linewidth=0.5)
453456
ax.add_patch(l1d)
454457
ax.text(x + x_spacing - 0.2, y - 0.8, f"L1 (d) {format_size(cache['size'])}",
455-
ha='center', va='center', fontsize=8)
458+
ha='center', va='center', fontsize=8, color=text_color)
456459

457-
# Draw L2 cache
458460
for group in l2_groups.values():
459461
if core in group['cores']:
460-
l2 = patches.Rectangle((x, y - 1.4), x_spacing * 2 - 0.4, 0.4, facecolor=l2_color)
462+
l2 = patches.Rectangle((x, y - 1.4), x_spacing * 2 - 0.4, 0.4,
463+
facecolor=l2_color, edgecolor='white', linewidth=0.5)
461464
ax.add_patch(l2)
462465
ax.text(x + x_spacing - 0.2, y - 1.2, f"L2 {format_size(group['size'])}",
463-
ha='center', va='center', fontsize=8)
466+
ha='center', va='center', fontsize=8, color=text_color)
464467
break
465468

466469
# Draw E-cores
467470
for i, core in enumerate(sorted(e_cores)):
468471
x = (i % e_cores_per_row) * x_spacing + e_section_start
469472
y = (i // e_cores_per_row) * y_spacing * 3
470-
rect = patches.Rectangle((x, y), core_width, core_height, facecolor=e_core_color)
473+
rect = patches.Rectangle((x, y), core_width, core_height,
474+
facecolor=e_core_color, edgecolor='white', linewidth=0.5)
471475
ax.add_patch(rect)
472-
ax.text(x + core_width/2, y + core_height/2, f"E{core}", ha='center', va='center')
476+
ax.text(x + core_width / 2, y + core_height / 2, f"E{core}", ha='center', va='center', color=text_color)
473477

474-
# Find L1 caches for this core
475478
for cache in cache_structure:
476479
if cache['level'] == 1 and core in cache['cores']:
477480
if cache['type'] == 2: # L1i
478-
l1i = patches.Rectangle((x, y - 0.6), core_width, 0.4, facecolor=l1_color)
481+
l1i = patches.Rectangle((x, y - 0.6), core_width, 0.4,
482+
facecolor=l1_color, edgecolor='white', linewidth=0.5)
479483
ax.add_patch(l1i)
480-
ax.text(x + core_width/2, y - 0.4, f"L1i {format_size(cache['size'])}",
481-
ha='center', va='center', fontsize=8)
484+
ax.text(x + core_width / 2, y - 0.4, f"L1i {format_size(cache['size'])}",
485+
ha='center', va='center', fontsize=8, color=text_color)
482486
elif cache['type'] == 1: # L1d
483-
l1d = patches.Rectangle((x, y - 1.0), core_width, 0.4, facecolor=l1_color)
487+
l1d = patches.Rectangle((x, y - 1.0), core_width, 0.4,
488+
facecolor=l1_color, edgecolor='white', linewidth=0.5)
484489
ax.add_patch(l1d)
485-
ax.text(x + core_width/2, y - 0.8, f"L1d {format_size(cache['size'])}",
486-
ha='center', va='center', fontsize=8)
490+
ax.text(x + core_width / 2, y - 0.8, f"L1d {format_size(cache['size'])}",
491+
ha='center', va='center', fontsize=8, color=text_color)
487492

488-
# Draw L2 cache for E-cores (shared between quads)
489493
if i % 4 == 0:
490494
for group in l2_groups.values():
491495
if core in group['cores']:
492-
l2_width = x_spacing * 4 - 0.4 # Width for 4 cores
493-
l2 = patches.Rectangle((x, y - 1.4), l2_width, 0.4, facecolor=l2_color)
496+
l2_width = x_spacing * 4 - 0.4
497+
l2 = patches.Rectangle((x, y - 1.4), l2_width, 0.4,
498+
facecolor=l2_color, edgecolor='white', linewidth=0.5)
494499
ax.add_patch(l2)
495-
ax.text(x + l2_width/2, y - 1.2, f"L2 {format_size(group['size'])}",
496-
ha='center', va='center', fontsize=8)
500+
ax.text(x + l2_width / 2, y - 1.2, f"L2 {format_size(group['size'])}",
501+
ha='center', va='center', fontsize=8, color=text_color)
497502
break
498503

499-
# Find and draw L3 cache
500-
for cache in cache_structure:
501-
if cache['level'] == 3:
502-
l3_width = total_width # Now spans the entire width including both P-cores and E-cores
503-
l3 = patches.Rectangle((0, -3), l3_width, 0.8, facecolor=l3_color)
504-
ax.add_patch(l3)
505-
ax.text(l3_width/2, -2.6, f"L3 {format_size(cache['size'])} (Shared)",
506-
ha='center', va='center')
507-
break
504+
# Draw L3 cache
505+
l3_caches = [cache for cache in cache_structure if cache['level'] == 3]
506+
for l3_cache in l3_caches:
507+
# Find the leftmost and rightmost cores that share this L3
508+
shared_cores = sorted(l3_cache['cores'])
509+
leftmost_core = min(shared_cores)
510+
rightmost_core = max(shared_cores)
511+
512+
# Calculate the x-coordinates for this L3 section
513+
if leftmost_core in p_cores:
514+
start_x = (leftmost_core % p_cores_per_row) * x_spacing
515+
else:
516+
# For E-cores, adjust the starting position (only if e_cores exists)
517+
if e_cores:
518+
e_core_index = sorted(e_cores).index(leftmost_core)
519+
start_x = e_section_start + (e_core_index % e_cores_per_row) * x_spacing
520+
else:
521+
continue # Skip if no E-cores exist but cache is for E-cores
522+
523+
if rightmost_core in p_cores:
524+
end_x = (rightmost_core % p_cores_per_row) * x_spacing
525+
else:
526+
# For E-cores, adjust the ending position (only if e_cores exists)
527+
if e_cores:
528+
e_core_index = sorted(e_cores).index(rightmost_core)
529+
end_x = e_section_start + (e_core_index % e_cores_per_row) * x_spacing
530+
else:
531+
continue # Skip if no E-cores exist but cache is for E-cores
532+
533+
l3_width = end_x - start_x + core_width
534+
535+
# Draw this L3 section
536+
l3 = patches.Rectangle((start_x, -3), l3_width, 0.8,
537+
facecolor=l3_color, edgecolor='white', linewidth=0.5)
538+
ax.add_patch(l3)
539+
ax.text(start_x + l3_width / 2, -2.6,
540+
f"L3 {format_size(l3_cache['size'])} (Cores {min(shared_cores)}-{max(shared_cores)})",
541+
ha='center', va='center', color=text_color)
542+
543+
# Create legend elements
544+
legend_elements = [
545+
patches.Patch(facecolor=p_core_color, edgecolor='white', label='Performance Cores (P-cores)'),
546+
patches.Patch(facecolor=e_core_color, edgecolor='white', label='Efficiency Cores (E-cores)'),
547+
patches.Patch(facecolor=l1_color, edgecolor='white', label='L1 Cache (Data & Instruction)'),
548+
patches.Patch(facecolor=l2_color, edgecolor='white', label='L2 Cache'),
549+
patches.Patch(facecolor=l3_color, edgecolor='white', label='L3 Cache (Shared)')
550+
]
551+
552+
# Add legend in the bottom right corner
553+
ax.legend(handles=legend_elements, loc='upper right', bbox_to_anchor=(0.98, 0.98),
554+
ncol=1, fancybox=True, shadow=True)
508555

509556
# Set plot limits and remove axes
510557
margin = 1
511558
ax.set_xlim(-margin, total_width + margin)
512559
ax.set_ylim(-4, max(p_rows, e_rows) * y_spacing * 3 + margin)
513560
ax.axis('off')
514561

515-
plt.title("CPU Topology with Cache Hierarchy")
562+
plt.title("CPU Topology with Cache Hierarchy", color=text_color, y=0.98)
563+
564+
# Set figure background to dark
565+
fig.patch.set_facecolor('#1C1C1C')
566+
ax.set_facecolor('#1C1C1C')
567+
516568
plt.tight_layout()
517569
plt.show()
518570

0 commit comments

Comments
 (0)