# mgpusim **Repository Path**: he-zhenhaook/mgpusim ## Basic Information - **Project Name**: mgpusim - **Description**: A high-performance, high-flexibility multi-GPU simulator. - **Primary Language**: Go - **License**: MIT - **Default Branch**: v2 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-12-07 - **Last Updated**: 2026-01-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Bitonic Sort GPU Benchmark 这是一个基于 MGPUSIM 模拟器的 GPU 位元排序(Bitonic Sort)基准测试项目。项目实现了高效的位元排序算法,并支持 Top-K 查询功能。 功能特性 ✅ 完整的位元排序算法 GPU 实现 ✅ 支持升序和降序排序 ✅ Top-K 结果提取功能 ✅ 多 GPU 支持 ✅ 统一内存支持 ✅ 每个阶段的验证和调试 ✅ 基于 MGPUSIM 的硬件模拟 项目结构 text bitsort/ ├── main.go # 主程序入口 ├── bitsort/ │ ├── benchmark.go # 基准测试主逻辑 │ └── kernels.hsaco # GPU 内核二进制文件 ├── README.md # 项目说明文档 └── go.mod # Go 模块文件 安装依赖 1. 安装 Go 确保已安装 Go 1.16 或更高版本。 2. 安装 MGPUSIM bash go get github.com/sarchlab/mgpusim/v4 3. 下载项目 bash git clone cd bitsort go mod download 快速开始 基本用法 go package main import ( "log" "github.com/sarchlab/mgpusim/v4/driver" "./bitsort" ) func main() { // 创建驱动 driver := driver.NewDriver() // 创建位元排序基准测试 benchmark := bitsort.NewBenchmark(driver) // 配置参数 benchmark.Length = 1024 // 排序数组长度 benchmark.OrderAscending = true // 升序排序 benchmark.TopK = 20 // 提取前20个元素 // 运行基准测试 benchmark.Run() // 验证结果 benchmark.Verify() // 访问排序结果 sortedArray := benchmark.outputData topKResult := benchmark.topKResult log.Printf("排序完成!数组长度: %d", benchmark.Length) log.Printf("Top %d 结果: %v", benchmark.TopK, topKResult) } 配置选项 选项 类型 默认值 说明 Length int - 排序数组的长度(必须为2的幂) OrderAscending bool true 排序顺序:true为升序,false为降序 TopK int 20 提取前K个元素,0表示提取全部 useUnifiedMemory bool false 是否使用统一内存 示例 示例1:基本排序 go func basicSort() { driver := driver.NewDriver() benchmark := bitsort.NewBenchmark(driver) benchmark.Length = 512 benchmark.OrderAscending = true benchmark.TopK = 10 benchmark.Run() benchmark.Verify() } 示例2:多GPU排序 go func multiGPUSort() { driver := driver.NewDriver() benchmark := bitsort.NewBenchmark(driver) // 选择多个GPU benchmark.SelectGPU([]int{0, 1, 2, 3}) benchmark.Length = 4096 benchmark.OrderAscending = false // 降序排序 benchmark.SetUnifiedMemory() // 使用统一内存 benchmark.Run() benchmark.Verify() } 示例3:自定义数据验证 go func customVerification() { driver := driver.NewDriver() benchmark := bitsort.NewBenchmark(driver) benchmark.Length = 256 benchmark.Run() // 手动验证排序结果 for i := 0; i < benchmark.Length-1; i++ { if benchmark.OrderAscending { if benchmark.outputData[i] > benchmark.outputData[i+1] { log.Printf("排序错误在位置 %d", i) } } } // 打印Top-K结果 if benchmark.TopK > 0 { log.Printf("Top %d 结果:", benchmark.TopK) for i, val := range benchmark.topKResult { log.Printf(" [%d]: %d", i, val) } } } 性能调优 1. 工作组大小优化 内核代码使用128个元素的共享内存,每个工作组处理128个元素: opencl __local uint local_data[128]; // 64个线程,每个处理2个元素 2. 内存访问优化 使用共享内存减少全局内存访问 合并内存访问模式 每个线程处理多个元素 3. 多GPU负载均衡 go // 自动分配工作项到多个GPU totalWIs := b.Length / 2 wiPerQueue := totalWIs / len(queues) remainder := totalWIs % len(queues) 内核算法说明 位元排序算法 位元排序是一种基于比较的并行排序算法,时间复杂度为 O(n log² n)。算法特点: 适用于并行处理 数据移动模式规则 适合GPU实现 内核实现要点 opencl // 主要步骤: // 1. 加载数据到共享内存 // 2. 计算比较对索引 // 3. 比较和交换元素 // 4. 写回全局内存 // 比较-交换逻辑 if (leftElement > rightElement) { if (sortIncreasing) { // 升序:交换 } } else { if (!sortIncreasing) { // 降序:交换 } } 调试和验证 启用详细日志 go // 启用每个阶段的验证 doPerPassVerify = true // 在benchmark.go中设置 var doPerPassVerify = true 调试输出 bash # 启用调试输出 export DEBUG=1 # 运行基准测试 go run main.go 故障排除 常见问题 数组长度不是2的幂 text Error: 数组长度必须是2的幂 解决方案:确保 Length 是2的幂(如 256, 512, 1024) 内存不足 text Error: GPU内存不足 解决方案:减小数组长度或使用多GPU 排序验证失败 text Error: array[i] > array[i+1] 解决方案:检查内核实现或启用 doPerPassVerify 进行逐阶段调试 调试技巧 go // 1. 检查输入数据 fmt.Printf("输入数据: %v\n", benchmark.inputData[:10]) // 2. 检查输出数据 fmt.Printf("输出数据: %v\n", benchmark.outputData[:10]) // 3. 检查Top-K结果 fmt.Printf("Top-K结果: %v\n", benchmark.topKResult) 基准测试 性能指标 排序时间 内存带宽利用率 GPU占用率 可扩展性(多GPU) 运行性能测试 go func runPerformanceTest() { sizes := []int{256, 512, 1024, 2048, 4096} for _, size := range sizes { benchmark := bitsort.NewBenchmark(driver.NewDriver()) benchmark.Length = size start := time.Now() benchmark.Run() elapsed := time.Since(start) log.Printf("大小: %d, 时间: %v", size, elapsed) } } 贡献指南 报告问题 在GitHub Issues中创建问题 包含复现步骤和错误信息 提供相关配置信息 提交代码 Fork 仓库 创建功能分支 提交更改 创建Pull Request 代码规范 遵循Go编码规范 添加必要的注释 编写单元测试 更新文档 许可证 本项目采用 MIT 许可证。详见 LICENSE 文件。 致谢 MGPUSIM - GPU模拟器框架 AMD ROCm - 内核代码基础 联系方式 项目维护者:[你的名字] 问题反馈:[GitHub Issues] 邮箱:[你的邮箱] 提示: 运行前请确保MGPUSIM环境配置正确,并安装所有必要的依赖。