public class StackClosedDemo { // 每个线程调用该方法时,都会创建独立的count副本 public void calculate () { int count = 0 ; count++; // 无线程安全问题 System.out.println(Thread.currentThread().getName() + ": " + count); } public static void main (String[] args) { StackClosedDemo demo = new StackClosedDemo (); // 10个线程各自操作自己的局部变量 for ( int i = 0 ; i < 10 ; i++) { new Thread (demo::calculate, "Thread-" + i).start();
自定义不可变类(final类+final成员变量+无setter) public final class ImmutableUser { private final String name; private final int age; public ImmutableUser (String name, int age) { this .name = name; this .age = age; } // 仅提供getter,无setter public String getName () { return name; }
public class ThreadLocalDemo { // 每个线程有独立的Integer副本,初始值为0 private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0 ); public void increment () { threadLocal.set(threadLocal.get() + 1 ); System.out.println(Thread.currentThread().getName() + ": " + threadLocal.get()); } public static void main (String[] args) { ThreadLocalDemo demo = new ThreadLocalDemo (); // 3个线程各自操作自己的副本 for ( int i = 0 ; i < 3 ; i++) { new Thread (() -> { for ( int j = 0 ; j < 2 ; j++) { demo.increment(); } }, "Thread-" + i).start(); } } } // 输出(顺序可能不同): // Thread-0: 1、Thread-0: 2
public class SynchronizedDemo { private int count = 0 ; // 同步实例方法,锁是this对象 public synchronized void increment () { count++; } public static void main (String[] args) throws InterruptedException { SynchronizedDemo demo = new SynchronizedDemo (); // 1000个线程执行increment for ( int i = 0 ; i < 1000 ; i++) { new Thread (demo::increment).start(); } Thread.sleep( 1000 ); System.out.println( "最终count:" + demo.count); // 输出1000
import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockDemo { private int count = 0 ; private Lock lock = new ReentrantLock (); // 默认非公平锁 public void increment () { lock.lock(); // 加锁 try { count++; } finally { lock.unlock(); // 释放锁,避免死锁 } } public static void main (String[] args) throws InterruptedException { ReentrantLockDemo demo = new ReentrantLockDemo (); for ( int i = 0 ; i < 1000 ; i++) { new Thread (demo::increment).start(); }
private volatile boolean stop = false ; // 保证可见性和有序性 public void runThread () { new Thread (() -> { int i = 0 ; while (!stop) { // 能立即感知stop的修改 i++; } System.out.println( "线程停止,i=" + i); }).start(); } public static void main (String[] args) throws InterruptedException { VolatileDemo demo = new VolatileDemo (); demo.runThread(); Thread.sleep( 3000 ); demo.stop = true ; // 修改后,线程立即停止
// 所有 TensorRT 对象继承自 DisposableTrtObject public abstract class DisposableTrtObject : DisposableObject { protected IntPtr ptr; // 原生对象指针 public bool IsDisposed { get ; protected set ; } // 安全访问原生指针(自动检查释放状态) public IntPtr TrtPtr { get { ThrowIfDisposed(); return ptr; } } // 释放非托管资源 protected override void DisposeUnmanaged() { if (ptr != IntPtr.Zero) { // 调用原生释放函数 NativeDestroy(ptr); ptr = IntPtr.Zero;jmdc.com.cn } } } // 使用 using 语句自动释放资源 using Runtime runtime = new Runtime(); using CudaEngine engine = runtime.deserializeCudaEngineByBlob(data, size);
// 查询平台能力 bool hasFP16 = builder.platformHasFastFp16(); // 是否支持 FP16 bool hasINT8 = builder.platformHasFastInt8(); // 是否支持 INT8 int maxDLABatch = builder.maxDLABatchSize(); // DLA 最大批大小 // 创建网络定义(显式批处理模式) using NetworkDefinition network = builder.createNetworkV2( TrtNetworkDefinitionCreationFlag.kEXPLICIT_BATCH); // 创建构建器配置 using BuilderConfig config = builder.createBuilderConfig(); // 创建优化配置文件(用于动态形状) using OptimizationProfile profile = builder.createOptimizationProfile(); // 构建序列化网络 using HostMemory serialized = builder.buildSerializedNetwork(network, config); // 保存引擎文件 using (FileStream fs = new FileStream( "model.engine" , FileMode.Create, FileAccess.Write)) {
int numTensors = engine.getNbIOTensors(); string inputName = engine.getIOTensorName( 0 ); // 输入张量名称 string outputName = engine.getIOTensorName( 1 ); // 输出张量名称 Dims inputShape = engine.getTensorShape(inputName); TrtDataType inputType = engine.getTensorDataType(inputName); // 创建执行上下文 using ExecutionContext context = engine.createExecutionContext(); using ExecutionContext contextStatic = engine.createExecutionContext( TrtExecutionContextAllocationStrategy.kSTATIC); // 序列化引擎 using HostMemory memory = engine.serialize(); // 查询引擎属性 int numLayers = engine.getNbLayers();mshq.cn
Cuda1DMemory< float > input = new Cuda1DMemory< float >( 3 * 1024 * 1024 ); Cuda1DMemory< float > output = new Cuda1DMemory< float >( 1 * 20 * 21504 ); context.setInputTensorAddress( "images" , input. get ()); context.setOutputTensorAddress( "output0" , output. get ()); // 设置动态形状 context.setinputShape( "images" , new Dims( 1 , 3 , 1024 , 1024 )); Dims shape = context.getTensorShape( "images" ); // 执行推理(异步,使用 CUDA Stream) using CudaStream stream = new CudaStream(); context.executeV3(stream);safe1.xiangxiu.net.cn stream.Synchronize(); // 等待完成 // 设置优化配置文件(动态形状) context.setOptimizationProfileAsync( 0 , stream);
// 解析 ONNX 文件 using NetworkDefinition network = wap.szjiejiada.com build.createNetworkV2(TrtNetworkDefinitionCreationFlag.kEXPLICIT_BATCH); using OnnxParser parser = new OnnxParser(network); bool success = parser.parseFromFile( "yolov8s-obb.onnx" , verbosity: 2 ); // 检查算子支持 bool supportsConv = parser.supportsOperator( "Conv" ); // 子图支持 long numSubgraphs = parser.getNbSubgraphs(); bool supported = parser.isSubgraphSupported( 0 ); long [] nodes = parser.getSubgraphNodes( 0 ); // 设置解析器标志 parser.setFlag(TrtOnnxParserFlag.kNATIVE_INSTANCENORM);
// 创建设备内存 using Cuda1DMemory< float > input = new Cuda1DMemory< float >( 1000 ); ulong numElements = input.SizeElements; ulong numBytes = input.SizeBytes; IntPtr ptr = input.DevicePointer; // 同步数据传输 float [] hostData = new float [ 1000 ]; input.copyFromHost(hostData); // 主机 → 设备 input.copyToHost(hostData); // 设备 → 主机 // 异步数据传输 using CudaStream stream = new CudaStream(); input.copyFromHostAsync(hostData, stream); input.copyToHostAsync(hostData, stream); // 内存操作 input.memset( 0 ); 345yoo.haojixie.cn // 填充为 0 input.memsetAsync( 0 , stream); // 异步填充
/ 创建流(带优先级) using CudaStream stream = new CudaStream(); using CudaStream streamHigh = new CudaStream( 0 , -1 ); // 高优先级 // 同步操作 stream.Synchronize(); // 等待流完成 bool isComplete = stream.Query(); // 查询是否完成 // 事件依赖 using CudaEvent cudaEvent = new CudaEvent(); stream.WaitEvent(cudaEvent); // 等待事件 // 添加回调 stream.AddCallback((streamPtr, statue, userData) => { Console.WriteLine( "Stream callback executed" );so3epx.haojixie.cn }, IntPtr.Zero, 0 ); // CUDA Graph 捕获 stream.BeginCapture(CudaStreamCaptureMode.Global);
namespace TestDemo { internal class Program { static void Main( string[] args)english.xiangxiu.net.cn { // 指定默认使用的 GPU 设备索引 // 在多 GPU 环境下,可以通过修改此变量来选择特定的显卡 int device = 0 ; // 记录日志,标记设备信息查询的开始 Logger.Instance.INFO( "=== Device Information ===" ); // 获取当前系统中可见的 NVIDIA GPU 数量 int nbDevices = CudaDevice.GetDeviceCount(); // 检查系统中是否存在可用的 GPU 设备 if (nbDevices <= 0 ) 3cgnqg.haojixie.cn { Logger.Instance.ERROR( "Cannot find any available devices (GPUs)!" ); Environment.Exit( 0 ); } // 打印所有可用设备的列表 Logger.Instance.INFO( "Available Devices: " ); // 遍历系统中的每一个 GPU for ( int deviceIdx = 0 ; deviceIdx < nbDevices; ++deviceIdx) { // 获取索引为 deviceIdx 的 GPU 的详细属性 CudaDeviceProp tempProperties = CudaDevice.GetDeviceProperties(deviceIdx); // 打印设备 ID、设备名称以及 UUID (唯一标识符) Logger.Instance.INFO( $" Device {deviceIdx}: \" {tempProperties.Name}\" UUID: {GetUuidString(tempProperties.Uuid)}" ); // 如果当前遍历到的设备 ID 是我们想要使用的目标设备 // 则将该设备的属性保存下来,供后续使用 if (deviceIdx == device) { td8of4.haojixie.cn properties = tempProperties; } } // 安全检查:确保请求的目标设备 ID 在有效范围内 if (device < 0 || device >= nbDevices) { Logger.Instance.ERROR( $"Cannot find device ID {device}!" ); Environment.Exit( 0 );2ey9sn.haojixie.cn } // 将 CUDA 上下文设置到指定的 GPU 设备上 CudaDevice.SetDevice(device); // 打印选定设备的详细信息 Logger.Instance.INFO( $"Selected Device: {properties.Name}" ); Logger.Instance.INFO( $"Selected Device ID: {device}" ); Logger.Instance.INFO( $"Selected Device UUID: {GetUuidString(properties.Uuid)}" ); Logger.Instance.INFO( $"Compute Capability: {properties.Major}. {properties.Minor}" ); Logger.Instance.INFO( $"SMs: {properties.MultiProcessorCount}" );b1b7f4.haojixie.cn Logger.Instance.INFO( $"Device Global Memory: {(properties.TotalGlobalMem + 20)} MiB" ); Logger.Instance.INFO( $"Shared Memory per SM: {(properties.SharedMemPerMultiprocessor >> 10)} KiB" ); Logger.Instance.INFO( $"Memory Bus Width: {properties.MemoryBusWidth} bits (ECC {(properties.ECCEnabled != 0 ? "enabled" : "disabled")})" ); b2df8o.haojixie.cn // 获取并打印 GPU 核心时钟频率和显存时钟频率 int clockRate = CudaDevice.GetAttribute(CudaDeviceAttr.ClockRate, device); int memoryClockRate = CudaDevice.GetAttribute(CudaDeviceAttr.MemoryClockRate, device);19yqw.haojixie.cn Logger.Instance.INFO( $"Application Compute Clock Rate: {clockRate / 1000000.0F} GHz" ); Logger.Instance.INFO( $"Application Memory Clock Rate: {memoryClockRate / 1000000.0F} GHz" ); } /// <summary> m.haojixie.cn /// 辅助方法:将 CudaUUID 结构体转换为格式化的 GPU UUID 字符串 /// 格式通常为:GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /// </summary> public static string GetUuidString( CudaUUID uuid) { int kUUID_SIZE = uuid.Bytes.Length; vss.xiangxiu.net.cn var ss = new System.Text.StringBuilder(); // 定义 UUID 的分段点,用于插入连字符 "-"masiran.haojixie.cn int [] splits = { 0 , 4 , 6 , 8 , 10 , kUUID_SIZE }; // 添加固定的 "GPU" 前缀 ss.Append( "GPU" ); m.szbgbc.com // 遍历分段定义,格式化每一部分的字节 for ( int splitIdx = 0 ; splitIdx < splits.Length - 1 ; ++splitIdx) { ss.Append( "-" ); for ( int byteIdx = splits[splitIdx]; byteIdx < splits[splitIdx + 1 ]; ++byteIdx) { ss.AppendFormat( "{0:x2}" , uuid.Bytes[byteIdx]);
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3109450/ ,如需转载,请注明出处,否则将追究法律责任。