搭建Qt4.8.7-armv7交叉编译环境
在Windows 10中搭建Qt 4.8.7 ARM32交叉编译环境,核心是获取ARM32交叉编译工具链、编译Qt 4.8.7源码适配ARM架构、配置环境变量与编译规则,以下是分步实操指南(全程需管理员权限,建议关闭杀毒软件避免文件拦截)。
一、前置准备:确定核心依赖与下载清单
Qt 4.8.7本身不提供预编译的ARM32交叉编译包,需手动编译源码,需下载以下组件(版本需严格匹配,避免兼容性问题):
| 组件名称 | 用途 | 下载地址/获取方式 |
| MinGW-w64(8.1.0) | Windows下的GCC编译环境 | SourceForge(选x86_64-posix-seh) |
| ARM32交叉编译工具链 | 编译ARM32架构程序 | 推荐Linaro 7.5.0(arm-linux-gnueabihf):Linaro官网 |
| Qt 4.8.7源码 | Qt核心源码(需适配ARM) | Qt Archive |
| Python 2.7.x | Qt 4.8.7编译依赖(必须2.7) | Python官网(选Windows x86-64 MSI) |
| Perl 5.28+ | Qt编译脚本依赖 | Strawberry Perl(选64位版本) |
| CMake 3.10+ | 辅助编译(可选但建议) | CMake官网(选Windows x64 Installer) |
| 7-Zip | 解压tar.gz/压缩包 | 7-Zip官网 |
二、步骤1:安装基础编译环境(Windows侧)
1.1 安装MinGW-w64
下载MinGW-w64后解压到固定路径(如
D:\mingw64),将D:\mingw64\bin添加到系统环境变量Path(优先级高于系统自带MinGW)。验证:打开CMD,输入
gcc -v,输出MinGW-w64 8.1.0版本信息则成功。
1.2 安装Python 2.7 + Perl + CMake
Python 2.7:安装时勾选“Add Python to PATH”,验证
python --version输出2.7.x。Strawberry Perl:默认安装即可,验证
perl -v输出5.28+版本。CMake:安装时勾选“Add CMake to the system PATH for all users”,验证
cmake --version输出3.10+。
三、步骤2:配置ARM32交叉编译工具链
2.1 解压并配置Linaro工具链
下载Linaro工具链(如
gcc-linaro-7.5.0-2019.12-i686-mingw32_arm-linux-gnueabihf.tar.xz),解压到固定路径(如D:\arm-linux-gnueabihf-7.5.0)。将工具链
bin目录(D:\arm-linux-gnueabihf-7.5.0\bin)添加到系统环境变量Path。验证:CMD输入
arm-linux-gnueabihf-gcc -v,输出Linaro 7.5.0版本信息则成功。
四、步骤3:修改Qt 4.8.7源码适配ARM交叉编译
Qt 4.8.7默认不支持Windows下ARM交叉编译,需手动修改配置文件:
4.1 解压Qt源码
将qt-everywhere-opensource-src-4.8.7.tar.gz用7-Zip解压到固定路径(如D:\qt-4.8.7-arm),避免路径含中文/空格。
4.2 修改交叉编译配置文件
Qt 4.8.7的交叉编译需通过mkspecs目录下的配置文件定义,步骤:
复制
D:\qt-4.8.7-arm\mkspecs\qws\linux-arm-gnueabi-g++目录,重命名为linux-arm-gnueabihf-g++(匹配Linaro工具链的hf(硬件浮点))。编辑新目录下的
qmake.conf,替换内容为:
1 | # 基础配置 |
注:
-march=armv7-a/-mtune=cortex-a9需根据目标ARM芯片调整(如ARMv6则改-march=armv6)。
五、步骤4:配置并编译Qt 4.8.7 ARM版本
5.1 生成编译配置(关键:避免Qt默认编译Windows版本)
打开MinGW-w64的CMD窗口(必须用MinGW的终端,而非系统CMD),执行以下命令:
1 | # 进入Qt源码根目录 |
参数说明:
-prefix:指定Qt ARM版本安装路径;-embedded arm:启用嵌入式ARM支持(Qt 4的QWS);-xplatform:指定步骤4.2中修改的交叉编译配置;禁用
webkit/phonon等非必需模块,减少编译时间和报错。
5.2 编译Qt源码
配置成功后(无error),执行编译命令:
1 | # 多核编译(-j后接CPU核心数,如8核则-j8) |
⚠️ 编译耗时(1-2小时),若报错:
检查工具链路径是否正确;
检查
qmake.conf中工具链前缀是否匹配;若提示“python找不到”,确保Python 2.7在PATH最前(Qt 4不兼容Python 3)。
5.3 安装编译后的Qt ARM版本
编译完成后执行:
1 | mingw32-make install |
安装完成后,D:\qt-4.8.7-arm-build即为可用于ARM32交叉编译的Qt环境。
六、步骤5:验证交叉编译环境
编写简单Qt测试程序,验证能否编译出ARM32可执行文件:
6.1 新建测试工程
在任意目录新建test.pro:
1 | QT += core gui |
新建main.cpp:
1 | #include <QApplication> |
6.2 用Qt ARM版本的qmake生成Makefile
打开MinGW终端,执行:
1 | # 指定ARM版本的qmake路径 |
6.3 编译生成ARM32程序
执行:
1 | mingw32-make |
编译完成后生成test可执行文件,用file命令(需安装Git for Windows,或复制到Linux)验证:
1 | # Git Bash中执行 |
输出类似test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked,说明成功生成ARM32程序。
七、常见问题与解决
configure阶段提示“无法找到arm-linux-gnueabihf-gcc”:
检查工具链
bin目录是否在PATH中,重启终端生效;确认工具链解压完整,无文件缺失。
编译阶段提示“undefined reference to xxx”:
禁用非必需模块(如webkit),Qt 4.8.7部分模块对ARM交叉编译支持差;
检查
qmake.conf中链接库参数(QMAKE_LIBS)是否完整。
Python版本错误:
- 卸载Python 3,仅保留Python 2.7,或在PATH中优先放置Python 2.7路径。
总结
Win10下Qt 4.8.7 ARM32交叉编译的核心是:
搭建MinGW+ARM交叉工具链环境;
修改Qt源码的交叉编译配置文件;
通过configure指定ARM编译参数,编译源码;
验证生成的程序为ARM32架构。
若追求效率,也可在Linux虚拟机中完成Qt 4.8.7 ARM交叉编译(Linux下交叉编译兼容性更好),再将编译结果复制到Windows使用。
Golang字符串拼接的6种方式
我们首先来了解一下 Go 语言中 string 类型的结构定义,先来看一下官方定义:
1 | // string is the set of all strings of 8-bit bytes, conventionally but not |
string 是一个 8 位字节的集合,通常但不一定代表UTF-8编码的文本。string可以为空,但是不能为nil。 string的值是不能改变的 。
string 类型本质也是一个结构体,定义如下:
1 | type stringStruct struct { |
stringStruct 和 slice 还是很相似的, str 指针指向的是某个数组的首地址, len 代表的就是数组长度。怎么和 slice 这么相似,底层指向的也是数组,是什么数组呢?我们看看他在实例化时调用的方法:
1 | //go:nosplit |
入参是一个 byte 类型的指针,从这我们可以看出 string 类型底层是一个 byte 类型的数组,所以我们可以画出这样一个图片:
![[Golang字符串拼接的6种方式/IMG-20251216170853116.png]]
string 类型本质上就是一个 byte 类型的数组,在 Go 语言中 string 类型被设计为不可变的,不仅是在 Go 语言,其他语言中 string 类型也是被设计为不可变的,这样的好处就是:在并发场景下,我们可以在不加锁的控制下,多次使用同一字符串,在保证高效共享的情况下而不用担心安全问题。
string 类型虽然是不能更改的,但是可以被替换,因为 stringStruct 中的 str 指针是可以改变的,只是指针指向的内容是不可以改变的,也就说每一个更改字符串,就需要重新分配一次内存,之前分配的空间会被 gc 回收。
关于 string 类型的知识点就描述这么多,方便我们后面分析字符串拼接。
字符串拼接的6种方式及原理
原生拼接方式”+”
Go 语言原生支持使用 + 操作符直接对两个字符串进行拼接,使用例子如下:
1 | var s string |
这种方式使用起来最简单,基本所有语言都有提供这种方式,使用 + 操作符进行拼接时,会对字符串进行遍历,计算并开辟一个新的空间来存储原来的两个字符串。
字符串格式化函数fmt.Sprintf
Go 语言中默认使用函数 fmt.Sprintf 进行字符串格式化,所以也可使用这种方式进行字符串拼接:
1 | str := "hello " |
fmt.Sprintf 实现原理主要是使用到了反射,具体源码分析因为篇幅的原因就不在这里详细分析了,看到反射,就会产生性能的损耗,你们懂得!!!
Strings.builder
Go 语言提供了一个专门操作字符串的库 strings ,使用 strings.Builder 可以进行字符串拼接,提供了 writeString 方法拼接字符串,使用方式如下:
1 | var builder strings.Builder |
strings.builder 的实现原理很简单,结构如下:
1 | type Builder struct { |
addr 字段主要是做 copycheck , buf 字段是一个 byte 类型的切片,这个就是用来存放字符串内容的,提供的 writeString() 方法就是像切片 buf 中追加数据:
1 | func (b *Builder) WriteString(s string) (int, error) { |
提供的 String 方法就是将 []]byte 转换为 string 类型,这里为了避免内存拷贝的问题,使用了强制转换来避免内存拷贝:
1 | func (b *Builder) String() string { |
bytes.Buffer
因为 string 类型底层就是一个 byte 数组,所以我们就可以 Go 语言的 bytes.Buffer 进行字符串拼接。 bytes.Buffer 是一个一个缓冲 byte 类型的缓冲器,这个缓冲器里存放着都是 byte 。使用方式如下:
1 | buf := new(bytes.Buffer) |
bytes.buffer 底层也是一个 []byte 切片,结构体如下:
1 | type Buffer struct { |
因为 bytes.Buffer 可以持续向 Buffer 尾部写入数据,从 Buffer 头部读取数据,所以 off 字段用来记录读取位置,再利用切片的 cap 特性来知道写入位置,这个不是本次的重点,重点看一下 WriteString 方法是如何拼接字符串的:
1 | func (b *Buffer) WriteString(s string) (n int, err error) { |
切片在创建时并不会申请内存块,只有在往里写数据时才会申请,首次申请的大小即为写入数据的大小。如果写入的数据小于64字节,则按64字节申请。采用动态扩展 slice 的机制,字符串追加采用 copy 的方式将追加的部分拷贝到尾部, copy 是内置的拷贝函数,可以减少内存分配。
但是在将 []byte 转换为 string 类型依旧使用了标准类型,所以会发生内存分配:
1 | func (b *Buffer) String() string { |
strings.join
Strings.join 方法可以将一个 string 类型的切片拼接成一个字符串,可以定义连接操作符,使用如下:
1 | baseSlice := []string{"hello", "world"} |
strings.join 也是基于 strings.builder 来实现的,代码如下:
1 | func Join(elems []string, sep string) string { |
唯一不同在于在 join 方法内调用了 b.Grow(n) 方法,这个是进行初步的容量分配,而前面计算的n的长度就是我们要拼接的slice的长度,因为我们传入切片长度固定,所以提前进行容量分配可以减少内存分配,很高效。
切片append
因为 string 类型底层也是 byte 类型数组,所以我们可以重新声明一个切片,使用 append 进行字符串拼接,使用方式如下:
1 | buf := make([]byte, 0) |
如果想减少内存分配,在将 []byte 转换为 string 类型时可以考虑使用强制转换。
Benchmark对比
上面我们总共提供了6种方法,原理我们基本知道了,那么我们就使用 Go 语言中的 Benchmark 来分析一下到底哪种字符串拼接方式更高效。我们主要分两种情况进行分析:
- 少量字符串拼接
- 大量字符串拼接
我们先定义一个基础字符串:
1 | var base = "123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASFGHJKLZXCVBNM" |
少量字符串拼接的测试我们就采用拼接一次的方式验证,base拼接base,因此得出benckmark结果:
1 | goos: darwin |
大量字符串拼接的测试我们先构建一个长度为200的字符串切片:
1 | var baseSlice []string |
然后遍历这个切片不断的进行拼接,因为可以得出 benchmark:
1 | goos: darwin |
通过两次 benchmark 对比,我们可以看到
- 当进行少量字符串拼接时,直接使用
+操作符进行拼接字符串,效率还是挺高的,但是当要拼接的字符串数量上来时,+操作符的性能就比较低了; - 函数
fmt.Sprintf还是不适合进行字符串拼接,无论拼接字符串数量多少,性能损耗都很大,还是老老实实做他的字符串格式化就好了; strings.Builder无论是少量字符串的拼接还是大量的字符串拼接,性能一直都能稳定,这也是为什么Go语言官方推荐使用strings.builder进行字符串拼接的原因,在使用strings.builder时最好使用Grow方法进行初步的容量分配,观察strings.join方法的benchmark就可以发现,因为使用了grow方法,提前分配好内存,在字符串拼接的过程中,不需要进行字符串的拷贝,也不需要分配新的内存,这样使用strings.builder性能最好,且内存消耗最小。bytes.Buffer方法性能是低于strings.builder的,bytes.Buffer转化为字符串时重新申请了一块空间,存放生成的字符串变量,不像strings.buidler这样直接将底层的[]byte转换成了字符串类型返回,这就占用了更多的空间。
同步最后分析的结论:
无论什么情况下使用 strings.builder 进行字符串拼接都是最高效的,不过要主要使用方法,记得调用 grow 进行容量分配,才会高效。 strings.join 的性能约等于 strings.builder ,在已经字符串slice的时候可以使用,未知时不建议使用,构造切片也是有性能损耗的;如果进行少量的字符串拼接时,直接使用 + 操作符是最方便也是性能最高的,可以放弃 strings.builder 的使用。
综合对比性能排序:
1 | strings.join ≈ strings.builder > bytes.buffer > []byte转换string > "+" > fmt.sprintf |
解决QDebug打印中文乱码问题
在使用 Qt 开发时,qDebug 打印包含中文的 QString 可能会出现乱码。这通常是由于字符编码不一致导致的。
1 | #include <QDebug> |
WindowsServer2016多用户远程登录配置
概述
Windows Server 2016默认情况下只允许一个用户通过远程桌面连接登录。通过配置远程桌面服务,可以实现多用户同时远程登录服务器,提高团队协作效率,避免用户争抢登录权限。
一、安装远程桌面服务
1.1 安装步骤
- 打开服务器管理器
- 点击添加角色和功能
- 在”服务器角色”页面,勾选远程桌面服务
- 继续选择远程桌面会话主机和远程桌面授权
- 完成安装向导,重启服务器

二、配置组策略设置
2.1 打开组策略编辑器
- 按
Win + R打开运行对话框 - 输入
gpedit.msc并回车
2.2 配置连接限制
- 导航到:计算机配置 → 管理模板 → Windows组件 → 远程桌面服务
- 双击打开 远程桌面会话主机 → 连接
- 找到并双击 限制连接的数量
- 选择 已启用
- 设置 允许的RD最大连接数(建议根据服务器性能设置,如10-20个)
- 点击 确定 保存设置

三、配置远程桌面授权(破解120天限制)
3.1 激活远程桌面授权服务器
- 打开 服务器管理器 → 工具 → 远程桌面服务 → 远程桌面授权管理器
- 右键点击服务器名称,选择 激活服务器
- 按照向导完成激活过程
3.2 安装许可证
- 在远程桌面授权管理器中,右键点击服务器
- 选择 安装许可证
- 按照向导选择合适的许可证类型
3.3 配置授权模式
- 打开组策略编辑器
- 导航到:计算机配置 → 管理模板 → Windows组件 → 远程桌面服务 → 远程桌面会话主机 → 授权
- 配置以下设置:
- 设置远程桌面授权模式:选择 按用户 或 按设备
- 指定远程桌面授权服务器:输入许可证服务器的地址
四、其他重要配置
4.1 用户权限配置
- 打开 服务器管理器 → 工具 → 计算机管理
- 导航到:系统工具 → 本地用户和组 → 组
- 双击 Remote Desktop Users 组
- 添加需要远程登录的用户或用户组
4.2 防火墙配置
确保防火墙允许远程桌面连接:
1 | # 允许远程桌面连接 |
4.3 性能优化
- 打开 系统属性 → 高级 → 性能设置
- 选择 调整为最佳性能 或根据需求自定义
- 在远程桌面会话主机配置中,可以调整:
- 会话超时设置
- 重定向设置
- 客户端体验设置
五、验证配置
5.1 测试多用户登录
- 从不同的客户端计算机同时使用远程桌面连接
- 使用不同的用户账户登录
- 验证所有用户都能成功连接
5.2 检查连接状态
- 在服务器上打开 任务管理器
- 切换到 用户 选项卡
- 查看当前登录的用户数量
5.3 监控性能
- 使用 性能监视器 监控服务器资源使用情况
- 关注CPU、内存和网络使用率
- 根据监控结果调整连接数量限制
六、故障排除
6.1 常见问题及解决方案
问题1:用户无法远程登录
解决方案:
- 检查用户是否已添加到Remote Desktop Users组
- 验证防火墙设置
- 检查网络连通性
问题2:连接数量达到上限
解决方案:
- 增加连接数量限制
- 检查是否有闲置会话未断开
- 配置会话超时设置
问题3:120天试用期警告
解决方案:
- 确保远程桌面授权已正确激活
- 安装有效的许可证
- 配置授权服务器设置
6.2 诊断命令
1 | # 查看远程桌面服务状态 |
七、安全建议
7.1 访问控制
- 使用强密码策略
- 启用账户锁定策略
- 定期审计用户权限
7.2 网络安全
- 更改默认的RDP端口(3389)
- 使用VPN进行远程访问
- 启用网络级别身份验证(NLA)
7.3 监控与审计
- 启用安全审计日志
- 监控异常登录尝试
- 定期检查系统日志
八、最佳实践
8.1 容量规划
- 根据服务器硬件配置合理设置最大连接数
- 每个用户建议分配至少1GB内存
- 监控性能指标,及时调整配置
8.2 维护计划
- 定期更新操作系统和安全补丁
- 备份重要配置和用户数据
- 定期测试灾难恢复计划
8.3 用户管理
- 建立清晰的用户权限管理制度
- 定期清理不再需要的用户账户
- 提供用户培训,确保正确使用远程桌面
总结
通过以上配置,Windows Server 2016可以支持多用户同时远程登录,显著提高团队协作效率。关键配置步骤包括:
- 安装远程桌面服务:包括远程桌面会话主机和授权服务
- 配置组策略:设置最大连接数和其他相关参数
- 激活授权服务:破解120天试用期限制
- 优化性能和安全:根据实际需求调整配置
建议在生产环境中部署前进行充分测试,确保配置满足业务需求和安全要求。定期维护和监控是保证系统稳定运行的重要保障。
Ubuntu18.04安装ROS-Melodic
系统要求
- 操作系统: Ubuntu 18.04 (Bionic Beaver)
- ROS 版本: Melodic Morenia (官方长期支持版本)
- Python 版本: 2.7.x (ROS Melodic 默认使用)
安装步骤
1. 配置软件源和密钥
1 | sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' |
2. 更新软件包列表
1 | sudo apt update |
3. 安装 ROS Melodic
完整桌面版 (推荐,包含 GUI 工具、仿真器和常用库):
1 | sudo apt install ros-melodic-desktop-full |
其他可选版本:
1 | sudo apt install ros-melodic-desktop # 基础桌面版(无仿真器) |
4. 初始化 rosdep
1 | sudo rosdep init |
5. 设置环境变量
1 | echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc |
6. 安装构建工具和依赖
1 | sudo apt install python-rosinstall python-rosinstall-generator python-wstool build-essential |
7. 创建示例工作空间 (可选)
1 | mkdir -p ~/catkin_ws/src |
验证安装
打开新终端,运行:
1 | roscore |
如果看到类似以下输出,说明安装成功:
1 | ... logging to /home/username/.ros/log/xxx/roslaunch-hostname-xxx.log |
常见问题解决
1. 密钥获取失败
如果 apt-key adv 失败,可以手动下载并添加:
1 | curl -sSL 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xC1CF6E31E6BADE8868B172B4F42ED6FBAB17C654' | sudo apt-key add - |
2. 网络问题
如果下载速度慢,可以替换为国内镜像源(如清华源):
1 | sudo sh -c '. /etc/lsb-release && echo "deb https://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' |
3. Python 版本验证
确保系统中已安装 Python 2.7:
1 | python --version # 应显示 Python 2.7.x |
测试命令
安装完成后,可以使用以下命令测试 ROS 功能:
roscore- 启动 ROS masterrosrun roscpp_tutorials talker- 运行发布者节点rosrun roscpp_tutorials listener- 运行订阅者节点
参考资源
Ubuntu部署LIO-SAM
概述
LIO-SAM (Lidar Inertial Odometry and Mapping) 是一个紧耦合的激光雷达惯性里程计框架,集成了 IMU 预积分和 GPS 数据,适用于机器人建图和定位。
环境要求
| 组件 | 版本 | 下载地址 |
|---|---|---|
| Ubuntu | 18.04+ | - |
| ROS | Melodic | - |
| gtsam | 4.0.2 | GitHub |
| Eigen | 3.3.7 | GitLab |
| LIO-SAM | 最新版 | GitHub |
安装步骤
1. 安装系统依赖
1 | # 更新系统包列表 |
2. 安装 Eigen 库
1 | # 下载并解压 Eigen |
3. 安装 ROS Melodic
1 | # 设置 ROS 软件源(清华镜像) |
4. 配置 ROS 环境
1 | # 将 ROS 环境变量添加到 bashrc |
5. 安装 gtsam
1 | # 克隆 gtsam 仓库 |
6. 安装 LIO-SAM
1 | # 创建工作空间 |
验证安装
测试 ROS 安装
1 | # 启动 ROS 核心 |
测试 LIO-SAM 编译
1 | # 检查 LIO-SAM 包是否存在 |
常见问题解决
1. Eigen 头文件找不到
问题:编译时出现 fatal error: Eigen/Dense: No such file or directory
解决方案:
1 | # 确保 Eigen 头文件在正确位置 |
2. gtsam 版本不兼容
问题:需要特定版本的 gtsam
解决方案:
1 | # 确保使用 gtsam 4.0.2 版本 |
3. ROS 依赖问题
问题:缺少 ROS 包依赖
解决方案:
1 | # 安装所有缺失的依赖 |
使用说明
启动 LIO-SAM
1 | # 启动 LIO-SAM 主要节点 |
数据播放
1 | # 播放 bag 文件 |
目录结构
1 | ~/catkin_ws/ |
注意事项
- 版本匹配:确保所有组件的版本兼容性
- 内存要求:编译过程需要足够的内存,建议 8GB+ RAM
- 网络连接:下载依赖需要稳定的网络连接
- 权限问题:某些操作需要 sudo 权限
后续步骤
- 配置参数:根据你的传感器调整
config/params.yaml - 数据采集:使用你的传感器采集数据
- 性能调优:根据实际场景调整算法参数
参考资源
nvidia-smi常用指令及其参数说明
一、什么是 NVIDIA-SMI?
nvidia-smi 是 NVIDIA 的系统管理界面(System Management Interface),用于监控和管理 NVIDIA GPU 设备。它是 NVIDIA 驱动安装包的一部分,无需额外安装。
核心功能:
- 监控:实时查看 GPU 状态、温度、功耗、显存使用率、进程占用等。
- 管理:修改 GPU 配置选项,如启用/禁用 ECC 内存、设置持久化模式、调整计算模式等。
- 诊断:查询设备拓扑、时钟速度、支持的功能等。
支持的产品:
- 完全支持:所有 Tesla(Fermi 架构起)、Quadro(Fermi 架构起)、GRID(Kepler 架构起)、GeForce Titan(Kepler 架构起)产品。
- 有限支持:所有 GeForce 产品(Fermi 架构起)。
二、基础信息查询命令
2.1 查看 GPU 概览信息
命令:nvidia-smi
这是最常用的命令,显示所有 GPU 的实时状态摘要。

输出字段详解:
| 字段 | 含义 |
|---|---|
| GPU | 本机中的 GPU 编号(从 0 开始) |
| Name | GPU 型号(如 Tesla V100) |
| Fan | 风扇转速(百分比) |
| Temp | GPU 核心温度(摄氏度) |
| Perf | 性能状态(P0-P12,P0 为最高性能) |
| Pwr:Usage/Cap | 当前功耗 / 最大设计功耗 |
| Bus-Id | PCI 总线 ID(格式:domain:bus:device.function) |
| Disp.A | Display Active,显示是否初始化 |
| Memory-Usage | 显存使用情况(已用 / 总量) |
| Volatile GPU-Util | GPU 计算单元利用率(百分比) |
| Uncorr. ECC | 未纠正的 ECC 错误计数 |
| Compute M. | 计算模式(Default, Exclusive_Process 等) |
| Processes | 显示占用该 GPU 的进程及其显存使用量 |
2.2 列出所有 GPU 设备
命令:nvidia-smi -L
以简洁格式列出系统中所有 NVIDIA GPU 设备。
1 | GPU 0: Tesla V100-SXM2-32GB (UUID: GPU-xxxxxx) |
2.3 查看系统拓扑
命令:nvidia-smi topo --matrix
显示 GPU 之间以及 GPU 与 CPU、其他 PCIe 设备(如 InfiniBand 网卡)的互连拓扑。这对于配置 GPUDirect 等高级功能至关重要。

三、高级查询与监控
3.1 查询详细 GPU 信息
命令:nvidia-smi -q
显示指定 GPU(或所有 GPU)的极其详细的信息报告。可以通过 -i <gpu_id> 指定 GPU。
报告包含的主要部分:
- GPU 基本信息:产品名称、序列号、UUID、VBIOS 版本等。
- PCI 信息:总线 ID、带宽、链路宽度等。
- 时钟信息:图形时钟、内存时钟、SM 时钟的当前值、默认值和最大值。
- 温度与功耗:当前温度、功耗限制、电源管理状态。
- 显存信息:总显存、已用显存、ECC 模式、BAR1 内存使用情况。
- ECC 错误:易失性和聚合性 ECC 错误计数。
- 计算进程:当前正在使用 GPU 的计算进程列表。

3.2 查询时钟信息
查看当前时钟:
nvidia-smi -q -d CLOCK
显示 GPU 的当前图形、内存和 SM 时钟速度,以及默认和最大时钟。
查看支持的时钟列表:
nvidia-smi -q -d SUPPORTED_CLOCKS
列出 GPU 支持的所有可用时钟速度组合。
3.3 虚拟 GPU (vGPU) 状态查询
命令:nvidia-smi vgpu
查看虚拟化环境中 vGPU 的状态信息。如果系统未启用 vGPU,会提示不支持。
动态监控 vGPU 进程:nvidia-smi vgpu -p
以滚动刷新的方式循环显示虚拟桌面中应用程序对 GPU 资源的占用情况。
四、设备管理与配置
4.1 设置持久化模式
命令:nvidia-smi -pm <0/1>
0或DISABLED:禁用持久化模式(默认)。GPU 驱动在最后一个客户端断开连接后会卸载。1或ENABLED:启用持久化模式。驱动始终保持加载状态,减少后续应用启动的延迟。1
2# 为 GPU 0 启用持久化模式
nvidia-smi -i 0 -pm 1
4.2 配置 ECC 内存
- 启用/禁用 ECC:
nvidia-smi -e <0/1>0或DISABLED:禁用 ECC。1或ENABLED:启用 ECC(需要重启生效)。
- 重置 ECC 错误计数:
nvidia-smi -p <0/1>0或VOLATILE:重置易失性错误计数。1或AGGREGATE:重置聚合性错误计数。
4.3 设置计算模式
命令:nvidia-smi -c <MODE>
控制 GPU 如何被计算应用程序共享。
| 模式值 | 模式名称 | 描述 |
|---|---|---|
0 |
DEFAULT |
多个计算应用可以共享 GPU(默认)。 |
1 |
EXCLUSIVE_THREAD |
已弃用。 |
2 |
PROHIBITED |
禁止任何计算应用使用 GPU。 |
3 |
EXCLUSIVE_PROCESS |
一个计算进程可以独占 GPU,该进程内的多个线程可共享。 |
1 | # 将 GPU 0 设置为独占进程模式 |
4.4 重置 GPU
命令:nvidia-smi -r
在 GPU 无响应或状态异常时,尝试触发 GPU 复位。此操作可能导致正在运行的进程崩溃,请谨慎使用。
五、实用参数与监控技巧
5.1 周期性监控
- 按秒间隔循环刷新:
nvidia-smi -l <秒数>
例如nvidia-smi -l 2每 2 秒刷新一次显示。 - 按毫秒间隔循环刷新:
nvidia-smi -lms <毫秒数>
例如nvidia-smi -lms 500每 500 毫秒刷新一次。
5.2 输出到文件
使用 -f 或 --filename 参数将输出重定向到文件,便于后续分析。
1 | # 将详细查询结果保存到文件 |
5.3 指定目标 GPU
使用 -i 或 --id 参数对特定的 GPU 进行操作。
1 | # 仅查看 GPU 1 的详细信息 |
5.4 以 XML 格式输出
使用 -x 或 --xml-format 参数,便于脚本解析。
1 | nvidia-smi -q -x |
六、命令参数速查表
| 参数类别 | 参数 | 功能描述 |
|---|---|---|
| 帮助 | -h, --help |
打印帮助信息。 |
| 列表 | -L, --list-gpus |
列出所有连接的 GPU。 |
| 查询 | -q, --query |
查询 GPU 详细信息。 |
-d, --display= |
选择性显示信息(如 MEMORY, CLOCK)。 |
|
| 目标 | -i, --id= |
指定目标 GPU ID(如 0, 0,2)。 |
| 输出 | -f, --filename= |
将输出保存到文件。 |
-x, --xml-format |
以 XML 格式输出。 | |
| 监控 | -l, --loop= |
按指定秒数间隔循环刷新。 |
-lms, --loop-ms= |
按指定毫秒数间隔循环刷新。 | |
| 管理 | -pm, --persistence-mode= |
设置持久化模式 (0/1)。 |
-e, --ecc-config= |
启用/禁用 ECC (0/1)。 | |
-c, --compute-mode= |
设置计算模式 (0-3)。 | |
-r, --gpu-reset |
触发 GPU 复位。 |
七、总结与最佳实践
nvidia-smi 是管理和监控 NVIDIA GPU 不可或缺的工具。掌握其核心用法:
- 日常监控:使用
nvidia-smi或nvidia-smi -l 1实时查看 GPU 状态。 - 问题诊断:使用
nvidia-smi -q获取详细报告,分析温度、功耗、ECC 错误和进程占用。 - 性能调优:通过
-pm、-c等参数调整 GPU 运行模式以适应不同工作负载。 - 自动化脚本:利用
-f、-x参数将输出重定向或格式化为 XML,便于集成到监控系统中。
官方资源:
- NVIDIA 管理库 (NVML) 开发者网站:http://developer.nvidia.com/nvidia-management-library-nvml/
- Python 绑定 (
nvidia-ml-py):http://pypi.python.org/pypi/nvidia-ml-py/
Ubuntu部署ROS
准备
建议准备一个干净、换好源的 Ubuntu 16.04 及以上版本(建议 清华源 ),本教程也适用其他 ROS1版本。
查看ubuntu 版本
1 | lsb_release -a |
根据自己的 Ubuntu 的版本选择 ROS 版本 (示例是 Ubuntu 18.04 所以对应ROS版本为 melodic)
![[Ubuntu部署ROS/IMG-20250829234441526.png]]
ROS安装
1. 安装源
1 | sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' |
2. 设置密钥
1 | sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 |
3. 安装
1 | sudo apt update |
4. 配置环境变量
1 | echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc |
5. 配置rosdep
在使用许多 ROS 工具之前,需要初始化 rosdep,有些功能包源码编译需要rosdep 来安装这些系统依赖项,不配置也不影响ros使用,所以后面需要时再来配置也可以。 rosdep 请求的文件都放在 github 上的, 推荐使用代理。
1 |
|
测试
1 | roscore |
参考
官方文档(melodic)
ubuntu18.04安装ROS Melodic(最详细配置)-CSDN博客
基于Ubuntu18.04的ROS Melodic环境详细配置(含各种大坑及填坑)
[ROS 系列学习教程] ROS与操作系统版本对应关系_ros版本-CSDN博客