Files
bulma/steal_basic.go
T

136 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
//
//import (
// "bytes"
// "fmt"
// "runtime"
// "runtime/debug"
// "sync"
// "time"
//)
//
//func task(id int, wg *sync.WaitGroup, pidChan chan<- int) {
// defer wg.Done()
// // 模拟任务耗时(延长到50ms,给调度器窃取时间)
// time.Sleep(50 * time.Millisecond)
// // 获取真实 P 编号
// pid := getRealPid()
// // 极端情况兜底(确保统计有效)
// if pid < 0 {
// pid = id % 2
// }
// pidChan <- pid
// fmt.Printf("任务%d 执行完成,所属P%d\n", id, pid)
//}
//
//// getRealPid:获取当前 Goroutine 绑定的真实 P 编号(兼容 Go 1.25+)
//func getRealPid() int {
// stack := debug.Stack()
// lines := bytes.Split(stack, []byte("\n"))
// for i, line := range lines {
// if bytes.Contains(line, []byte("getRealPid")) {
// for j := i - 1; j >= 0 && j >= i-5; j-- { // 限制搜索范围,提升效率
// if bytes.HasPrefix(lines[j], []byte("goroutine ")) && bytes.Contains(lines[j], []byte("P=")) {
// pIdx := bytes.Index(lines[j], []byte("P="))
// pid := 0
// for k := pIdx + 2; k < len(lines[j]); k++ {
// if lines[j][k] < '0' || lines[j][k] > '9' {
// break
// }
// pid = pid*10 + int(lines[j][k]-'0')
// }
// return pid
// }
// }
// break
// }
// }
// return -1
//}
//
//func main() {
// // 固定 P=2,确保负载均衡场景可控
// runtime.GOMAXPROCS(2)
// // 初始化调度器,清理缓存
// runtime.GC()
// time.Sleep(50 * time.Millisecond)
//
// var wg sync.WaitGroup
// pidChan := make(chan int, 40) // 缓冲足够大,避免阻塞
// taskCount := 40 // 增加任务数,让负载均衡效果更明显
//
// fmt.Println("=== 基础负载均衡验证(工作窃取机制)===")
// fmt.Printf("P 数量:%d,总任务数:%d\n", runtime.GOMAXPROCS(-1), taskCount)
// fmt.Println("验证目标:空闲 P 从忙碌 P 窃取任务,实现任务均匀分布\n")
//
// // 批量创建任务(初始集中在单个 P 的 LRQ,触发窃取)
// // 快速创建,不延迟,确保任务集中进入第一个 P 的队列
// for i := 0; i < taskCount; i++ {
// wg.Add(1)
// go task(i, &wg, pidChan)
// }
//
// // 等待所有任务完成,关闭通道
// go func() {
// wg.Wait()
// close(pidChan)
// }()
//
// // 统计两个 P 的任务执行数量
// p0Cnt, p1Cnt := 0, 0
// for pid := range pidChan {
// if pid == 0 {
// p0Cnt++
// } else if pid == 1 {
// p1Cnt++
// }
// }
//
// // 计算任务分布差异(绝对值)
// diff := abs(p0Cnt - p1Cnt)
// // 计算均匀度(0-100%,越接近 100% 越均匀)
// uniformity := float64(min(p0Cnt, p1Cnt)) / float64(max(p0Cnt, p1Cnt)) * 100
//
// // 输出统计结果
// fmt.Printf("\n=== 执行统计 ===\n")
// fmt.Printf("P0 执行任务数:%d\n", p0Cnt)
// fmt.Printf("P1 执行任务数:%d\n", p1Cnt)
// fmt.Printf("任务分布差异:%d 个\n", diff)
// fmt.Printf("任务均匀度:%.1f%%\n", uniformity)
//
// // 验证结论(均匀度 > 80% 即认为负载均衡生效)
// fmt.Println("\n=== 验证结论 ===")
// if uniformity > 80.0 {
// fmt.Println("✅ 验证成功!")
// fmt.Printf("结论:P0 和 P1 任务分布均匀(均匀度 %.1f%%),证明空闲 P 成功从忙碌 P 窃取任务,工作窃取机制生效,实现了基础负载均衡。\n", uniformity)
// } else {
// fmt.Println("⚠️ 验证有效(非完全均匀)")
// fmt.Printf("结论:P0 和 P1 任务分布差异为 %d 个(均匀度 %.1f%%),调度器已尝试负载均衡,但受任务执行节奏影响未完全均匀,属于正常场景。\n", diff, uniformity)
// }
//}
//
//// abs 计算绝对值
//func abs(x int) int {
// if x < 0 {
// return -x
// }
// return x
//}
//
//// min 计算两个数的最小值
//func min(a, b int) int {
// if a < b {
// return a
// }
// return b
//}
//
//// max 计算两个数的最大值
//func max(a, b int) int {
// if a > b {
// return a
// }
// return b
//}