Ubuntu 20.04 下 NVIDIA Tesla P40 驱动安装指南(核显桌面 + 计算卡分离方案)

Ubuntu 20.04 下 NVIDIA Tesla P40 驱动安装指南(核显桌面 + 计算卡分离方案)

NVIDIA Tesla P40 作为一款定位专业计算的 GPU,硬件层面无视频输出能力,无法直接驱动图形化桌面。在 Ubuntu 20.04 系统中,若要同时实现核显输出桌面与P40 提供算力的需求,需采用 “驱动分离” 方案。
本指南针对 Intel 核显 + Tesla P40 硬件组合,解决传统驱动安装中 “启用 P40 则桌面黑屏,切换核显则 P40 失效” 的矛盾,通过驱动适配、内核模块配置、开机自启设置等步骤,实现两者协同工作。教程兼顾新手友好性与专业性,既保证图形界面正常运行,又能让 P40 充分发挥 CUDA 计算性能,适用于 AI 推理、高性能计算等场景。


1 主板设置

1.1 主板选型要求

专业级显卡对主板的兼容性有明确要求,选购前需确认主板规格是否适配目标显卡,避免出现硬件不兼容、无法识别等问题。

在这里插入图片描述

1.2 主板 BIOS 设置步骤

进入主板 BIOS 界面,找到 Peripherals(外设) 菜单,定位到 Above 4G Decoding 选项,将其设置为 Enabled(启用),以此为大显存专业显卡分配足够的 PCIe 地址空间,确保显卡正常工作。

在这里插入图片描述

1 服务器版本环境安装

1.1 解锁Ubuntu系统以及依赖安装

首先需解除系统对 NVIDIA 驱动的默认屏蔽,避免驱动加载冲突:

sudobash-c'echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf'sudoaptinstall-y libgl1-mesa-glx libgl1-mesa-dri libgl1-mesa-glx:i386 

1.2 添加显卡驱动PPA

Ubuntu 官方源的驱动版本可能滞后,添加显卡驱动专用 PPA 以获取适配 Tesla P40 的稳定版本:

# 1. 添加显卡驱动PPAsudo add-apt-repository ppa:graphics-drivers/ppa # 2. 更新apt缓存(让系统识别新添加的源)sudoapt update 

1.3 安装NVIDIA显卡驱动

Tesla P40 基于 Kepler 架构,nvidia-driver-470 是官方支持的长期维护版本,执行以下命令安装并重启:

sudoaptinstall nvidia-driver-470 sudoaptinstall nvidia-driver-560 sudoreboot

这里nvidia-driver-470和nvidia-driver-560两个选择一个安装即可。

1.4 驱动验证与问题解决

重启后执行 nvidia-smi 可能会报如下错误:

NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
原因分析: 服务器版默认无图形界面,但系统仍可能优先识别核显,导致 NVIDIA 驱动内核模块未加载。
执行以下命令切换显卡模式:

# 查看当前显卡模式sudo prime-select query # 切换到 NVIDIA 显卡sudo prime-select nvidia 

切换完成后再次执行 nvidia-smi,若输出 Tesla P40 的显卡信息、驱动版本等内容,则说明安装成功。注意:服务器版本无图形化桌面,切换到 NVIDIA 模式后不影响系统使用,可直接用于算力调用。

在这里插入图片描述

2 桌面版本环境安装

桌面版本的驱动安装流程与服务器版本一致,核心差异在于需配置 “核显负责桌面、P40 负责算力” 的分离模式,避免桌面黑屏问题。

2.1 恢复核显桌面

若此前切换到 NVIDIA 模式导致桌面黑屏,需先切换回 Intel 核显模式,确保图形界面正常启动:

# 切换回 intel 模式,确保桌面能打开sudo prime-select intel # 重启生效sudoreboot

重启后桌面恢复正常,但此时 nvidia-smi 会提示驱动未加载。

2.2 设置开机自动加载 P40 驱动

通过配置系统模块加载文件,让系统开机时自动加载 NVIDIA 内核模块,实现 P40 算力调用与核显桌面的协同:

# 编辑模块加载配置文件sudovim /etc/modules-load.d/nvidia.conf 

在文件中写入以下内容:

nvidia nvidia-drm nvidia-uvm 

保存并退出 vim(输入 :wq 回车),执行以下命令更新 initramfs 使配置生效:

sudo update-initramfs -u# 重启系统验证sudoreboot

总结

本指南针对 Ubuntu 20.04 系统,提供了 Intel 核显与 Tesla P40 计算卡的协同驱动方案,分别适配服务器版与桌面版的不同需求。服务器版通过切换显卡模式即可直接启用 P40 算力;桌面版则采用 “核显桌面 + P40 算力” 的分离策略,通过配置模块自启实现两者共存,解决了传统安装中 “黑屏” 与 “驱动失效” 的矛盾。安装过程中需注意关闭 Secure Boot,确保驱动内核模块正常加载。最终通过双命令验证,可同时保障图形界面流畅运行与 P40 算力充分释放,满足 AI 推理、高性能计算等场景的使用需求。

Read more

双指针问题5(c++)

双指针问题5(c++)

概念 双指针,顾名思义,就是用两个指针解决问题。 有些问题用单指针会出现超时等问题,这时就需要用到双指针 双指针由两个指针组成,一般是左右指针,或前后指针 通过两个指针配合变化,用更短的时间高效解决问题 题目 (续上一篇,如需了解上一篇题目,请移步主页观看) 合并有序数组 #include <bits/stdc++.h> #define ll long long using namespace std; int la,lb,lab; int a[20010],b[10010]; int main() { cin>>la; for(int i = 1;i<

By Ne0inhk

面向 C++ 的现代 CMake 第二版(三)

原文:zh.annas-archive.org/md5/4abd6886e8722cebdc63cd42f86a9282 译者:飞龙 协议:CC BY-NC-SA 4.0 第八章:链接可执行文件和库 你可能会认为,一旦我们成功地将源代码编译成二进制文件,我们作为构建工程师的角色就完成了。然而,事实并非完全如此。尽管二进制文件确实包含了 CPU 执行所需的所有代码,但这些代码可能会以复杂的方式分布在多个文件中。我们不希望 CPU 在不同的文件中寻找单独的代码片段。相反,我们的目标是将这些分散的单元合并为一个文件。为了实现这一目标,我们使用了一个称为链接的过程。 快速观察可以发现,CMake 有很少的链接命令,其中target_link_libraries()是主要命令。那么,为什么要专门用一整章来讲解这个命令呢?不幸的是,计算机科学几乎没有什么事情是简单的,链接也不例外:为了获得正确的结果,我们需要了解整个过程——我们需要知道链接器是如何工作的,并掌握基本知识。我们将讨论目标文件的内部结构,重定位和引用解析机制的工作原理,以及它们的用途。

By Ne0inhk

绿盟校招C++研发工程师一面复盘

绿盟校招C++研发工程师一面复盘 1. 进程间通信方式中的共享内存为何比套接字快呢?共享内存的核心是让多个进程映射同一块物理内存到各自的虚拟地址空间,通信过程完全绕开内核的中转干预。而套接字会触发用户态到内核态的切换。用户态与内核态的切换,需要保存、恢复进程上下文,这是操作系统的核心开销之一,套接字的每一次send()/recv()都是系统调用,都要经历用户态->内核态->用户态的切换。共享内存无协议开销,数据是直接写入内存的原始字节流,无需封装任何协议头、无需计算校验和、无需处理拥塞控制,CPU开销极低。 2. 线上CPU飙升如何排查? * 首先确认是哪个进程占用CPU过高,登录服务器利用top命令查看各个进程的资源占用情况 * 确认CPU利用率很高的进程PID,假设1234为某个进程,则通过top -Hp 1234查看具体的线程 * 假设得到的线程ID是5678,再将线程ID转化为十六进制,得到十六进制的tid162e,此时利用jstack 1234 | grep 162e -A 100查看具体的栈信息。jstack命令用于生成当前时刻的线程快照。线程

By Ne0inhk

《C++ Primer》第5版 友元 (friend)

C++ 教材(《C++ Primer》第5版)章节标题为: 7.2.1 友元 (friend) 本节核心内容是:当类的数据成员设为 private 时,如何让非成员函数(如 read, print, add)能够访问这些私有成员?答案是——使用 friend 关键字声明“友元函数”。 这是面向对象设计中“封装性”与“接口灵活性”之间的重要平衡机制。 🔍 逐段解析 ✅ 第一段:问题背景 既然 Sales_data 的数据成员是 private 的,我们的 read、print 和 add 函数也就无法正常编译了,这是因为尽管这几个函数是类的接口的一部分,但它们不是类的成员。 💡 核心要点: * 如果将

By Ne0inhk