HP平台编译out of memory 问题的解决方法

博客介绍了通过修改系统内核参数解决问题的方法。使用kmtune可查看系统内核参数,如maxdsiz和maxssiz,修改这两个参数能解决问题,增加大小依据服务器物理内存估计使用,还给出了11i系统4G物理内存的参数示例。
修改系统内核参数:
   使用kmtune可以查看系统内核参数 
maxdsiz            1073741824  -  1073741824
maxssiz              0x800000  -  0X800000
修改如上两个参数可以解决问题,至于增加的大小依据服务器物理内存估计使用。
例如上面的参数是修改过的,服务器是11i的系统4G物理内存。

如有需要讨论,请使用邮件 conquer@vip.sina.com
<think>我们有一个C++编写的感知模块,编译为可执行文件,运行在GPU上。我们需要评估它在GPU上的计算性能(FLOPS)。 由于是已经编译好的可执行文件,我们无法直接修改代码插入计时代码(除非有源码并重新编译),但我们可以通过以下两种方法结合: 方法1:使用性能分析工具(如NVIDIA Nsight Systems/Compute)来收集GPU内核的执行时间,并计算实际FLOPS。 方法2:在代码中插入计时和FLOP计数(如果有源码)。 然而,用户提到的是已经编译为可执行文件的模块,因此我们主要使用方法1,同时可能需要结合方法2(如果有源码)。 具体步骤: 1. 使用性能分析工具(如Nsight Systems)运行可执行文件,收集GPU上每个kernel的执行时间以及硬件计数器的信息(包括执行的浮点运算指令数)。 注意:需要硬件计数器支持,这可能需要管理员权限。 2. 如果没有硬件计数器,我们可以通过以下方式估算: a. 通过Nsight Compute分析每个kernel的指令组成,统计浮点运算指令(如FADD, FMUL, FFMA等)的数量。 b. 然后,每个kernel的FLOPS = (浮点运算指令数 * 每个指令的浮点操作次数 * 线程块数量 * 每个线程块中的线程数) / 执行时间(秒) 但是,注意:FFMA(乘加)指令通常算作两次浮点运算(乘和加)。 3. 如果没有源码,但知道算法,可以估算每个kernel的浮点运算次数(FLOPs)。例如,对于一个矩阵乘法,我们知道FLOPs为2*M*N*K(每个元素计算需要乘法和加法)。 4. 然后,实际FLOPS = 总FLOPs / 执行时间(秒)。 但是,由于我们的感知模块可能包含多个kernel,我们需要分别计算每个kernel的FLOPS,然后求和得到整个模块的FLOPS。 然而,更直接的方法是使用工具直接获取浮点运算指令数。NVIDIA Nsight Compute可以做到这一点。 具体操作: 步骤1:使用Nsight Systems进行整体性能分析,确定关键kernel。 步骤2:使用Nsight Compute对关键kernel进行详细分析,收集以下指标: - 执行时间(duration) - 执行的浮点运算指令数(例如:flop_count_sp, flop_count_dp, flop_count_hp等,根据精度) - 或者更直接的是:sm__sass_thread_inst_executed_op_fadd_pred_on, sm__sass_thread_inst_executed_op_fmul_pred_on, sm__sass_thread_inst_executed_op_ffma_pred_on等。 注意:不同架构的GPU,指令计数可能不同。 步骤3:计算每个kernel的FLOPS: - 对于每个kernel,总的浮点操作次数 = (FADD指令数 + FMUL指令数 + 2 * FFMA指令数) * 活动线程数(实际上,每个线程执行的指令数已经包含在计数器里,但要注意计数器给出的是整个kernel的指令数,所以不需要再乘线程数) 解释:因为FFMA指令一次完成乘加(a*b+c),所以算两次浮点操作。 但是,Nsight Compute有一个指标叫做“SM Active Cycles”,以及“Achieved FLOPS”等。实际上,Nsight Compute可以直接报告FLOPS,但需要开启相应的指标集合。 具体操作: 1. 使用Nsight Compute命令行工具收集指标: ```bash nv-nsight-cu-cli -k <kernel_name> -f -o report <your_executable> ``` 或者使用Nsight Compute的GUI。 2. 在Nsight Compute的GUI中,我们可以选择要收集的指标集合,例如“flop_rates”或“sm_efficiency”。然后,运行程序,它会给出每个kernel的FLOPS(例如:GPU Speed Of Light Throughput - FP32等)。 3. 直接查看报告中的“SM [%]”部分,通常会有浮点运算的吞吐量(例如:FP16, FP32, FP64的FLOPS)。 注意:由于GPU是并行执行的,实际FLOPS会根据GPU的占用率、内存带宽等因素而低于理论峰值。 如果没有工具,或者工具使用受限,我们可以采用以下替代方法方法:在程序中插入时间戳(使用CPU计时)测量整个感知模块的运行时间,同时通过算法分析计算整个模块的浮点运算总数(FLOPs)。然后,FLOPS = 总FLOPs / 运行时间。 但是,这种方法需要知道算法细节和计算量,对于复杂的感知模块可能难以准确计算。 因此,推荐使用Nsight Compute工具。 示例步骤: 1. 安装Nsight Compute(通常包含在CUDA Toolkit中)。 2. 使用以下命令收集指标(以FP32为例): ```bash nv-nsight-cu-cli --metrics smsp__sass_thread_inst_executed_op_fadd_pred_on.sum,smsp__sass_thread_inst_executed_op_fmul_pred_on.sum,smsp__sass_thread_inst_executed_op_ffma_pred_on.sum <your_executable> <args> ``` 注意:具体的指标名称可能因架构而异。也可以使用更高级的指标组,如: ```bash nv-nsight-cu-cli --metrics gpu__time_duration.avg,sm__sass_thread_inst_executed_op_fadd_pred_on.sum,sm__sass_thread_inst_executed_op_fmul_pred_on.sum,sm__sass_thread_inst_executed_op_ffma_pred_on.sum <your_executable> <args> ``` 3. 解析输出,对于每个kernel: 总FLOPs = (FADD + FMUL + 2 * FFMA) # 因为FFMA算两次 执行时间(单位秒)可以通过gpu__time_duration.avg(单位纳秒)除以1e9得到。 然后,该kernel的FLOPS = 总FLOPs / 执行时间 4. 整个模块的FLOPS = 所有kernel的FLOPS之和(但注意,这里的FLOPS是每个kernel的峰值,而整个模块的FLOPS应该是总FLOPs除以总时间?实际上,我们通常关注的是整个模块运行期间的平均FLOPS,所以应该用所有kernel的总FLOPs除以整个模块的运行时间(包括内存传输等)?这取决于需求。如果只关心计算性能,可以只计算kernel执行期间的平均FLOPS,忽略内存传输时间;如果关心端到端性能,则应该包括所有时间。 注意:在GPU程序中,通常有内存传输(Host<->Device)和kernel执行,而FLOPS一般只考虑计算部分。 因此,我们通常报告的是计算部分的FLOPS,即所有kernel的总FLOPs除以这些kernel执行的总时间(不包括内存传输)。 但是,用户可能关心整个模块的吞吐量,那么就要用总FLOPs除以整个模块的运行时间(包括内存传输等)。所以需要明确。 建议:同时报告纯计算FLOPS(即kernel执行期间的FLOPS)和整体FLOPS(包括内存传输等)。 总结: 对于基于C++开发并编译为可执行文件的感知模块,评估其在GPU上的FLOPS的步骤: 1. 使用Nsight Compute工具运行可执行文件,收集每个kernel的浮点运算指令数和执行时间。 2. 计算每个kernel的FLOPs(浮点运算次数)和FLOPS(FLOPs per second)。 3. 汇总所有kernel的FLOPs和执行时间,得到整个模块的计算FLOPS(总FLOPs / 总kernel执行时间)。 4. 同时,可以测量整个程序运行时间(端到端),计算整体FLOPS(总FLOPs / 程序总运行时间)。 注意:如果程序中有其他非计算操作(如内存传输)占用了大量时间,整体FLOPS会低于计算FLOPS。 如果没有Nsight工具,或者无法使用,可以考虑在代码中嵌入计时(如果有源码): - 使用CUDA事件记录每个kernel的开始和结束时间。 - 同时,通过算法分析得到每个kernel的FLOPs(需要手动计算)。 - 然后,计算每个kernel的FLOPS。 示例代码(如果有源码): 在调用kernel之前和之后插入CUDA事件: ```cpp cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); cudaEventRecord(start); myKernel<<<grid, block>>>(...); cudaEventRecord(stop); cudaEventSynchronize(stop); float milliseconds = 0; cudaEventElapsedTime(&milliseconds, start, stop); ``` 然后,根据已知的该kernel的FLOPs(通过算法计算),计算FLOPS: FLOPS = (FLOPs) / (milliseconds * 1e-3); // 因为时间是毫秒,要转秒 但是,这种方法需要预先知道每个kernel的FLOPs,对于复杂kernel可能难以计算。 因此,工具方法更为推荐。 引用说明: 使用性能分析工具(如Nsight Systems/Compute)来收集GPU内核的执行时间以及硬件计数器信息,是评估GPU计算性能的标准方法[^1]。 同时,在引用[2]中提到了GPU的理论峰值FLOPS(如A100为19.5 TFLOPS),但实际FLOPS需要通过测量得到。 注意:以上方法主要针对NVIDIA GPU,如果是其他厂商的GPU,需要使用对应的工具。 最后,生成相关问题:</think>### 评估C++感知模块在GPU上的FLOPS性能 评估基于C++开发并编译为可执行文件的感知模块在GPU上的FLOPS性能,需要结合硬件性能计数器和代码分析技术。以下是具体实施步骤: #### 1. **使用NVIDIA Nsight Compute工具** 这是最精确的方法,通过硬件计数器直接测量浮点运算指令数: ```bash # 安装Nsight Compute sudo apt install nvidia-nsight-compute # 运行性能分析(需root权限) sudo nv-nsight-cu-cli --metrics smsp__sass_thread_inst_executed_op_fadd_pred_on.sum, \ smsp__sass_thread_inst_executed_op_fmul_pred_on.sum, \ smsp__sass_thread_inst_executed_op_ffma_pred_on.sum \ ./your_perception_module ``` **关键指标解释**: - `smsp__sass_thread_inst_executed_op_fadd_pred_on.sum`:单精度加法指令数 - `smsp__sass_thread_inst_executed_op_fmul_pred_on.sum`:单精度乘法指令数 - `smsp__sass_thread_inst_executed_op_ffma_pred_on.sum`:乘加指令(FFMA算2次浮点操作) **FLOPS计算公式**: $$ \text{Total FLOPS} = \frac{(\text{FADD} + \text{FMUL} + 2 \times \text{FFMA}) \times \text{Warp Size}}{\text{GPU Time (s)}} $$ 其中Warp Size通常为32(NVIDIA GPU)[^1]。 #### 2. **CUDA事件计时法(需源码修改)** 若可修改源码,插入CUDA事件计时: ```cpp #include <cuda_runtime.h> void run_perception_module() { cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); // 在GPU计算代码前后插入事件 cudaEventRecord(start); perception_kernel<<<blocks, threads>>>(...); // GPU计算核心 cudaEventRecord(stop); cudaEventSynchronize(stop); float ms = 0; cudaEventElapsedTime(&ms, start, stop); // 计算FLOPS (需提前估算FLOPs) double flops = (estimated_flops / (ms * 1e-3)); std::cout << "Achieved FLOPS: " << flops / 1e12 << " TFLOPS" << std::endl; } ``` #### 3. **算法级FLOPs估算** 通过分析算法计算量估算理论FLOPs: - **卷积层示例**: $$ \text{FLOPs} = 2 \times K_h \times K_w \times C_{in} \times C_{out} \times H_{out} \times W_{out} $$ 其中$K$=卷积核尺寸,$C$=通道数,$H/W$=输出尺寸 - **矩阵乘法示例**: $$ \text{FLOPs} = 2 \times M \times N \times K $$ 其中$M,N,K$是矩阵维度 #### 4. **结合系统级监控** ```bash # 实时监控GPU利用率 nvidia-smi --query-gpu=utilization.gpu,power.draw --format=csv -l 1 # 使用Nsight Systems捕获时间线 nsys profile -o report.qdrep ./your_perception_module ``` **结果分析要点**: - 计算密集型kernel应满足:$\text{GPU Util} > 70\%$ - 若$\text{Memory Copy Time} > \text{Kernel Time}$,存在瓶颈[^1] - 实际FLOPS与理论峰值比值(如A100的19.5 TFLOPS[^2]) #### 5. **优化验证技巧** - **精度对比**:测试FP32/FP16性能差异 ```bash nv-nsight-cu-cli --metrics sm__throughput.avg.pct_of_peak_sustained_elapsed ``` - **瓶颈分析**: - 计算瓶颈:提高SM占用率(Occupancy) - 内存瓶颈:使用共享内存或减少bank冲突 > **注**:对于黑盒可执行文件,若无法使用Nsight工具,可通过算法FLOPs估算结合`nvidia-smi`的GPU利用率近似计算: > $$ \text{实际FLOPS} = \text{理论峰值} \times \text{GPU Util\%} \times \text{Kernel时间占比} $$ ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值