什么是ILGPU?
ILGPU 是一种用于高性能 GPU 程序的新型 JIT(即时)编译器 (也称为 kernels)编写的 .基于 Net 的语言。ILGPU 完全 用 C# 编写,没有任何原生依赖项,允许您编写 GPU 真正可移植的程序。
ILGPU有什么用?
它将 C++ AMP 的便利性与 CUDA 的高性能相结合。 内核范围内的函数不必进行注释(例如默认的 C# 函数),并允许处理值类型。所有内核(包括所有 可以执行共享内存、原子和 Warp Shuffle 等硬件功能 并使用集成的多线程 CPU 加速器在 CPU 上进行调试。
本文介绍几个核心的功能
1.ILGPU 核心类
Context
用途:管理 GPU 上下文,提供设备查询和加速器创建功能。
代码示例
using var context = Context.CreateDefault();
Accelerator
用途:表示物理加速器(如 GPU 或 CPU),用于执行内核和分配内存。
代码示例
using var accelerator = context.GetPreferredDevice(preferCPU: false).CreateAccelerator(context);
2.GPU 内存管理
Allocate1D<T>
用途:在 GPU 上分配一维内存缓冲区。
代码示例
private MemoryBuffer1D<float, Stride1D.Dense> _positionBuffer;
_positionBuffer = _accelerator.Allocate1D<float>(MaxVehicleCount);
CopyFromCPU
/ CopyToCPU
用途:在 CPU 和 GPU 之间复制数据。
代码示例
_positionBuffer.View.CopyFromCPU(stream, positions);
_positionBuffer.View.CopyToCPU(stream, positions);
3.内核 (Kernel) 操作
LoadAutoGroupedStreamKernel
用途:加载并编译 GPU 内核函数,自动优化线程分组。
代码示例
var kernel = accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<int>, ArrayView<int>, ArrayView<int>>(VectorAddKernel);
内核函数定义
要求:内核函数必须是 static
,参数需包含索引和 ArrayView
代码示例
static void UpdateVehicleState(Index1D index,ArrayView1D<float, Stride1D.Dense> positions,ArrayView1D<float, Stride1D.Dense> speeds,ArrayView1D<float, Stride1D.Dense> lengths,float deltaTime)
{if (index < positions.Length){positions[index] += speeds[index] * deltaTime;if (positions[index] > lengths[index]){positions[index] = lengths[index];}}
}
内核函数定义
要求:内核函数必须是 static
,参数需包含索引和 ArrayView
。
代码示例
static void UpdateVehicleState(Index1D index,ArrayView1D<float, Stride1D.Dense> positions,ArrayView1D<float, Stride1D.Dense> speeds,ArrayView1D<float, Stride1D.Dense> lengths,float deltaTime)
{if (index < positions.Length){positions[index] += speeds[index] * deltaTime;if (positions[index] > lengths[index]){positions[index] = lengths[index];}}
}
启动内核
kernel((int)deviceA.Length, deviceA.View, deviceB.View, deviceResult.View);
4.流 (Stream) 操作
DefaultStream
用途:获取加速器的默认流,用于同步和异步操作。
using (var stream = _accelerator.DefaultStream)
{// 执行数据复制和内核启动
}
Synchronize
用途:等待流中所有操作完成。
stream.Synchronize();
5. 设备信息
PrintInformation
用途:输出加速器详细信息(如 GPU 型号、内存大小)。
using (var stringWriter = new StringWriter())
{gpuDevice.PrintInformation(stringWriter);string info = stringWriter.ToString();Console.WriteLine($"GPU信息:{info}");
}
6. 异常处理与资源释放
Dispose
用途:释放 GPU 内存缓冲区,避免内存泄漏。
public void Dispose()
{_positionBuffer?.Dispose();_speedBuffer?.Dispose();_lengthBuffer?.Dispose();
}
7. 多设备支持
遍历设备
用途:查找支持 CUDA 的 GPU,若未找到则回退到 CPU。
foreach (Device device in context.Devices)
{if (device.AcceleratorType == AcceleratorType.Cuda){gpuDevice = device.CreateAccelerator(context);break;}
}
if (gpuDevice == null)
{gpuDevice = context.GetCPUDevices()[0].CreateAccelerator(context);
}