///|
fn main {
println("==================================================")
println(
" MoonSim 云计算数据中心仿真示例:多租户GPU抢占与调度 ",
)
println("==================================================")
let sim = @moonsim.Simulation::new()
let gpu_cluster = @resource.PreemptibleResource::new("NVIDIA-H800集群", 4)
let spot_tracker = @stats.PercentileTracker::new("Spot任务响应时间(ms)")
let vip_tracker = @stats.PercentileTracker::new("VIP任务响应时间(ms)")
let mut spot_id = 1
let mut vip_id = 1
let mut spot_completed = 0
let mut vip_completed = 0
let mut spot_preempted = 0
// 1. Low-priority Spot Batch Job Generator (prio=10)
let spot_steps : Array[(@event.ProcessContext) -> Double?] = [
fn(ctx) {
if spot_id <= 6 {
let jid = spot_id
spot_id = spot_id + 1
let arrival = ctx.clock.now_seconds()
println(
"[\{arrival}s] [Spot批处理] 任务 #\{jid} 申请 2卡 GPU (优先级=10)",
)
let _ = gpu_cluster.request(
2,
10,
fn(holder) {
if holder is Some(_) {
let start = sim.now()
println(
"[\{start}s] [Spot批处理] 任务 #\{jid} 成功获取 2卡 GPU,开始训练",
)
let _ = sim.schedule(4.0, 10, fn() {
// A preempted job can still have this delayed event in the
// queue. It must not release a new holder or count as done.
let holder_id = holder.unwrap()
if gpu_cluster.is_holder_active(holder_id) {
gpu_cluster.release(holder_id)
spot_completed = spot_completed + 1
let dur = (sim.now() - arrival) * 1000.0
spot_tracker.record(dur)
println(
"[\{sim.now()}s] [Spot批处理] 任务 #\{jid} 训练完成释放 GPU!总耗时: \{dur}ms",
)
} else {
println(
"[\{sim.now()}s] [Spot批处理] 任务 #\{jid} 已被抢占,忽略过期完成事件",
)
}
})
}
},
fn() {
spot_preempted = spot_preempted + 1
println(
"[\{sim.now()}s] [!!! 资源抢占 !!!] [Spot批处理] 任务 #\{jid} 被高优先级 VIP 业务抢占并驱逐出集群!",
)
},
)
Some(1.2) // New spot job every 1.2s
} else {
None
}
},
]
let _ = sim.start_process(
sim.register_process("Spot作业生成器", spot_steps),
0.0,
10,
)
// 2. High-priority VIP Online Job Generator (prio=1)
let vip_steps : Array[(@event.ProcessContext) -> Double?] = [
fn(ctx) {
if vip_id <= 3 {
let vid = vip_id
vip_id = vip_id + 1
let arrival = ctx.clock.now_seconds()
println(
"\n[\{arrival}s] [+++ VIP推理 +++] 紧急任务 #\{vid} 申请 3卡 GPU (最高优先级=1)",
)
let _ = gpu_cluster.request(
3,
1,
fn(holder) {
if holder is Some(_) {
let start = sim.now()
println(
"[\{start}s] [VIP推理] 任务 #\{vid} 瞬间分配并独占 3卡 GPU!等待时间: \{(start - arrival)*1000.0}ms",
)
let _ = sim.schedule(1.5, 1, fn() {
gpu_cluster.release(holder.unwrap())
vip_completed = vip_completed + 1
let dur = (sim.now() - arrival) * 1000.0
vip_tracker.record(dur)
println(
"[\{sim.now()}s] [VIP推理] 紧急任务 #\{vid} 计算完成出库,释放 GPU 资源池。",
)
})
}
},
fn() { println("[\{sim.now()}s] [VIP任务被抢占异常]") },
)
Some(3.0) // VIP burst arrives at t=2.0, t=5.0, t=8.0
} else {
None
}
},
]
let _ = sim.start_process(
sim.register_process("VIP在线业务网关", vip_steps),
2.0,
1,
)
sim.run_until(15.0)
println("\n==================================================")
println(" 云原生集群调度分析报告 ")
println("==================================================")
println("仿真虚拟总时长: \{sim.now()}s")
println(
"VIP高优先级业务完结数: \{vip_completed} (响应时间 P50: \{vip_tracker.p50()}ms, P99: \{vip_tracker.p99()}ms)",
)
println("Spot低优先级批处理完结数: \{spot_completed}")
println("触发优先级抢占驱逐次数: \{spot_preempted}")
println("==================================================\n")
}