【linux内核专栏 05】中断与下半部

发布时间:2026/10/2 17:18:45

【linux内核专栏 05】中断与下半部 本篇定位:Linux 中断架构比裸机复杂得多——RISC-V 直接配 PLIC,Linux 要经irq_domain 框架;FreeRTOS ISR 只能调 FromISR API,Linux 强制顶半部 下半部分离(顶半部不能睡不能耗时)。本篇把Linux 中断对你已知的 RISC-V trap/PLIC、FreeRTOS ISR 的增量讲透。读完能正确选 softirq/workqueue/threaded irq、能调中断丢失/风暴、能写 threaded irq 驱动。MCU相关中断知识是 Linux 中断的子集,核心增量是顶半部下半部强制分离FreeRTOS ISR:快进快出,用 FromISR API 通知任务。Linux 中断强制分两层:顶半部(硬中断):硬件中断,关中断(或低优先级开),不能睡不能耗时,只做确认中断 拷贝数据 调度下半部下半部:耗时/可睡的活推迟到这里,三种实现(softirq/tasklet/workqueue)为什么强制?因为 Linux 中断可能打断任意上下文(甚至其他中断),耗时 全系统卡顿。这是 FreeRTOS(任务少,ISR 可稍长)到 Linux(进程多,ISR 必须极短)的硬约束。一、Linux 中断架构总览硬件中断(PLIC/GIC 发出) │ ▼ ┌─────────────────────────────┐ │ ① 异常入口(arch/riscv/kernel/entry.S) │ 保存上下文,跳 C └─────────────────────────────┘ │ ▼ ┌─────────────────────────────┐ │ ② 通用中断处理(handle_irq) │ 找 virq 对应的 action 链 └─────────────────────────────┘ │ ▼ ┌─────────────────────────────┐ │ ③ 顶半部(你的 ISR,handler) │ 硬中断上下文,不能睡 │ request_irq 注册的 handler │ 确认拷贝触发下半部 └─────────────────────────────┘ │ 标记下半部 ▼ ┌─────────────────────────────┐ │ ④ 下半部(softirq/tasklet/workqueue) │ 可稍耗时,workqueue 可睡 └─────────────────────────────┘关键抽象:hwirq vs virqhwirq(硬件中断号):硬件/中断控制器给的号(如 PLIC source 5)virq(虚拟中断号):Linux 内核用的线性号(从 0 开始)irq_domain:hwirq ↔ virq 的翻译层,让驱动用统一的 virq,不关心硬件细节PLIC source 5 ──irq_domain── virq 42 ──驱动 request_irq(42, handler)irq_domain 是 Linux 中断的虚拟化RISC-V 直接配 PLIC,知道 source 5。Linux 驱动不直接用 source 5——它从设备树拿中断号,经 irq_domain 翻译成 virq,用 virq 注册。这层抽象让驱动跨平台(同驱动跑不同 PLIC 版本/GIC/AIA)。你 BSP 写中断驱动,走 irq_domain 框架,不直接碰 PLIC 寄存器。二、中断控制器驱动(irqchip)2.1 irqchip 框架中断控制器(PIC)本身也是设备,有驱动(irqchip driver)irqchip 驱动注册到irq_domain,提供:① 中断号翻译;② 中断使能/禁用;③ 优先级/亲和性;④ ack/eoi(确认/结束中断)PLIC 驱动:drivers/irqchip/irq-sifive-plic.cGIC 驱动:drivers/irqchip/irq-gic*.c2.2 PLIC 在 Linux 里你 [[05-中断系统 PLIC-CLINT-AIA]] 学的 PLIC(priority/enable/threshold/claim-complete),Linux 里被irq-sifive-plic.c封装:你裸机操作Linux PLIC 驱动写 priority[src]plic_irq_set_type / set_affinity写 enable[src]plic_irq_unmaskclaim 读plic_irq_eoi 前的 handlecomplete 写plic_irq_eoi你不直接写 PLIC 寄存器,irqchip 驱动替你写。驱动用 virq,irqchip 翻译成 hwirq 操作 PLIC。2.3 设备树描述中断uart10000000 { compatible myvendor,uart; reg 0x10000000 0x100; interrupts 10; /* hwirq 10(PLIC source 10) */ interrupt-parent plic; /* 归属 PLIC */ };驱动从设备树解析interrupts,经 irq_domain 翻译成 virq,request_irq(virq, ...)。2.4 中断处理流程(RISC-V)1. PLIC 拉中断线 → CPU stvec 跳 entry.S 2. entry.S 保存上下文,跳 handle_arch_irq 3. handle_arch_irq → plic handle(claim 读 hwirq) 4. irq_domain 翻译 hwirq → virq 5. generic_handle_irq(virq) → 找 action 链 → 调你的 handler(顶半部) 6. handler 返回 IRQ_HANDLED 7. plic eoi(写 complete) 8. entry.S 检查 need_resched → 可能 schedule 9. 恢复上下文,中断返回(sret)三、顶半部(硬中断上下文)3.1 顶半部的约束硬中断上下文(hardirq context)的硬规则:❌不能睡眠(不能调 schedule/mutex/might_sleep)❌不能持有需要睡眠的锁(mutex)❌不能耗时(影响其他中断/系统响应)✅ 能用自旋锁(自旋锁关抢占不睡)✅ 能分配 GFP_ATOMIC✅ 能调local_irq_disable/enable3.2 注册中断:request_irq// 驱动里注册中断intretrequest_irq(virq,// 中断号my_handler,// 顶半部 handlerIRQF_TRIGGER_FALLING,// 触发类型my_uart,// 名字(显示在 /proc/interrupts)dev);// 传给 handler 的参数(通常 dev 指针)if(ret){/* 失败 */}// 释放free_irq(virq,dev);3.3 handler 原型staticirqreturn_tmy_handler(intirq,void*dev_id){structmy_dev*devdev_id;// 1. 确认中断(读状态寄存器)if(!(readl(dev-baseSTATUS)IRQ_PENDING))returnIRQ_NONE;// 不是我的中断// 2. 拷贝数据(快)datareadl(dev-baseDATA);// 3. 清中断(必须,否则反复触发)writel(IRQ_CLEAR,dev-baseSTATUS);// 4. 触发下半部schedule_work(dev-work);// 或 tasklet_schedule / raise_softirqreturnIRQ_HANDLED;}返回值:IRQ_HANDLED:是我的中断,处理了IRQ_NONE:不是我的(共享中断时判断)IRQ_WAKE_THREAD:唤醒关联的线程化处理(threaded irq)3.4 共享中断(IRQF_SHARED)多个设备共用一根中断线:request_irq(virq, h1, IRQF_SHARED, dev1, dev1)request_irq(virq, h2, IRQF_SHARED, dev2, dev2)中断来时,内核依次调 h1/h2/…,每个判断是不是自己的(读状态寄存器),是就处理返回 IRQ_HANDLED,不是返回 IRQ_NONE3.5 对照 FreeRTOS ISRFreeRTOS ISRLinux 顶半部能睡❌❌调阻塞 API❌(只能 FromISR)❌耗时可稍长(任务少)必须极短通知任务xQueueSendFromISRschedule_work 等关中断taskENTER_CRITICALlocal_irq_saveFreeRTOS ISR 经验直接迁移,但更严你 FreeRTOS ISR 懂快进快出 用 FromISR API 通知——Linux 顶半部完全同构。增量是 Linux 更严:① 顶半部耗时影响全系统(不只本任务);② 共享中断要判断是不是自己的;③ 必须清中断(裸机你也会忘,但 Linux 反复触发更明显)。四、下半部三件套:softirq / tasklet / workqueue ⭐4.1 为什么三种下半部要推迟执行,但场景不同:softirq编译期静态注册优先级最高、延迟最低多核可完全并行但必须可重入驱动一般不能新增类型主要留给网络栈、定时器、块设备等核心子系统。tasklet基于 softirq 封装接口简单同一个 tasklet 实例不会在多个 CPU 上并发天然串行安全但它运行在软中断上下文不可睡眠且并发能力弱内核社区已在推动逐步淘汰。workqueue运行在进程上下文kworker 内核线程可以睡眠能用 mutex、msleep、GFP_KERNEL 分配内存驱动最常用。4.2 选哪个(决策树)下半部要睡眠吗? 是 ── workqueue(唯一可睡) 否 ── 要性能? 是 ── 老代码用 tasklet,新代码用 threaded irq 否 ── workqueue(简单) 或:threaded irq(现代首选,见 §五)4.3 softirq(性能最高,驱动用不到)类型固定(NET_RX/TX/BLOCK/TASKLET/HRTIMER/RCU 等)open_softirq(NR, fn)注册(内核核心,驱动不能)raise_softirq(NR)标记触发在中断返回时(ksoftirqd 内核线程或中断尾)执行同类型 softirq 可多核并行(无锁要小心)// 内核核心代码示例(驱动不会这么用)open_softirq(NET_RX_SOFTIRQ,net_rx_action);raise_softirq(NET_RX_SOFTIRQ);4.4 tasklet(基于 softirq,弃用中)// 驱动用(但新代码别用)structtasklet_structt;tasklet_init(t,my_tasklet_fn,(unsignedlong)data);tasklet_schedule(t);// 在顶半部触发voidmy_tasklet_fn(unsignedlongdata){// 下半部逻辑,不能睡}基于 TASKLET_SOFTIRQ同 tasklet 不会并行(同核或多核都串行),比 softirq 安全弃用原因:多核性能差(全局锁),新代码用 threaded irq 替代嵌入式视角:别用 tasklet,老驱动除外你看老驱动大量用 tasklet。新内核(5.x)建议改 threaded irq 或 workqueue。tasklet 在并发场景性能差(全局锁串行),且社区在淘汰。你写新驱动别用,读老驱动认识即可。4.5 workqueue(可睡眠,最常用)⭐// 1. 定义 work(静态)structmy_dev{structwork_structwork;...};INIT_WORK(dev-work,my_work_fn);// 2. 顶半部触发schedule_work(dev-work);// 调度到默认 workqueue(系统共享)// 3. work 函数(可睡!)voidmy_work_fn(structwork_struct*w){structmy_dev*devcontainer_of(w,structmy_dev,work);// 可以睡:mutex/sleep/IO/kmalloc(GFP_KERNEL)msleep(10);mutex_lock(dev-lock);...mutex_unlock(dev-lock);}4.6 workqueue 的几种用法API特点schedule_work(w)默认 workqueue(系统共享,events 线程)schedule_delayed_work(w, delay)延迟执行alloc_workqueue()queue_work()自建 workqueue(可并发控制)system_long_wq系统长任务 workqueue4.7 自建 workqueuestructworkqueue_struct*my_wqalloc_workqueue(my_wq,0,0);queue_work(my_wq,dev-work);// 用完destroy_workqueue(my_wq);自建 workqueue 可控制并发(单线程/多线程)、优先级适合不想被其他驱动拖累的场景workqueue 是你下半部主力你写驱动下半部,默认用 workqueue——它能睡,API 简单,系统共享 workqueue 够用。只有性能极致场景才考虑 threaded irq 或自建 workqueue。对照 FreeRTOS:workqueue 像你ISR 通知任务,任务里慢慢处理,work_struct 就是那个任务的一个工作项。五、threaded irq(现代首选)⭐5.1 什么是 threaded irq把顶半部 下半部合并成硬中断 中断线程:顶半部只做确认中断 返回 IRQ_WAKE_THREAD内核唤醒一个专属内核线程跑你的处理函数处理函数在进程上下文(可睡!)// 注册 threaded irqintretrequest_threaded_irq(virq,my_hardirq,// 顶半部(可 NULL,全交给线程)my_thread_fn,// 线程处理(可睡)IRQF_ONESHOT,// 顶半部后禁中断直到线程跑完my_dev,dev);// 顶半部staticirqreturn_tmy_hardirq(intirq,void*dev){// 只做最少:确认 决定要不要线程if(!(readl(baseSTATUS)IRQ_PENDING))returnIRQ_NONE;returnIRQ_WAKE_THREAD;// 唤醒线程}// 线程处理(可睡)staticirqreturn_tmy_thread_fn(intirq,void*dev){// 可睡:mutex/IO/kmalloc(GFP_KERNEL)msleep(1);handle_data(dev);returnIRQ_HANDLED;}5.2 IRQF_ONESHOT顶半部执行后,中断保持禁用,直到线程跑完才重新使能防止线程处理时中断又来(数据竞争)threaded irq 几乎必加5.3 为什么 threaded irq 是现代首选维度workqueuethreaded irq专属线程❌(系统共享)✅(每中断一线程)优先级控制难✅(调线程优先级,实时)中断禁用保护手动IRQF_ONESHOT 自动RT-Linux 友好一般✅(天然线程化)实时性:threaded irq 线程可设 RT 优先级,关键中断优先处理调试:线程有名字(/proc//comm),好定位RT-Linux:threaded irq 是 PREEMPT_RT 的基础(硬中断最小化)[!important] 新驱动首选 threaded irq你写新驱动下半部,首选 threaded irq(request_threaded_irq)。它比 workqueue 更适合中断场景:① 专属线程不被其他驱动拖累;② 可设优先级;③ IRQF_ONESHOT 自动保护;④ RT-Linux 友好。workqueue 适合不紧急的延迟工作,threaded irq 适合中断的下半部。5.4 force threaded(强制线程化)内核配置CONFIG_IRQ_FORCED_THREADING,或 cmdlinethreadirqs,把所有中断强制线程化。用于 RT-Linux 调试。六、中断上下文 vs 进程上下文硬中断上下文(顶半部)软中断上下文(softirq/tasklet)进程上下文(workqueue/threaded irq)可睡❌❌✅可持 mutex❌❌✅可持 spinlock✅(关抢占)✅✅可 kmallocGFP_ATOMICGFP_ATOMICGFP_KERNEL可调 schedule❌❌✅被打断可被其他中断可被硬中断可被中断/抢占调试难中易(有进程上下文)中断上下文不能睡是铁律不管顶半部还是 softirq/tasklet,只要不在进程上下文就不能睡。睡了 → schedule → 切走 → 但中断上下文不属于任何进程,切不回来 → panic/死锁。你 FreeRTOS 临界区里能睡(切到其他任务),Linux 中断上下文绝对不能——这是大差异。七、中断亲和性(IRQ Affinity)7.1 什么是亲和性把某中断绑定到特定 CPU多核系统:不同中断跑不同核,均衡负载实时:关键中断绑到专用核,不被打扰7.2 设置# 看中断cat/proc/interrupts# CPU0 CPU1# 10: 12345 0 UART (全在 CPU0)# 绑到 CPU1(掩码)echo2/proc/irq/10/smp_affinity# 2 二进制 10 CPU1# 看cat/proc/irq/10/smp_affinity7.3 驱动里设cpumask_tmask;cpumask_clear(mask);cpumask_set_cpu(1,mask);// CPU1irq_set_affinity(virq,mask);[note] 嵌入式视角:多核中断绑核你 AEGIX split 双核,中断可绑核:① 网络中断绑核0;② 实时控制中断绑核1 专用;③ 避免中断都挤一个核。这是多核 BSP 调优手段。对照你 RISC-V PLIC 每核独立 enable/threshold,Linux 亲和性就是控制每核的 enable。八、中断风暴与丢失8.1 中断风暴中断来得太快,顶半部不停跑,CPU 全耗在中断,用户进程饿死。排查:cat/proc/interrupts# 看某中断计数暴涨watch-n1cat /proc/interrupts | grep mydev原因:中断没清干净(反复触发)硬件故障(信号抖动/电平不稳)设备异常(疯狂发中断)解法:确认顶半部清中断用 level-triggered 改 edge(或反之)中断线程化 限流关中断轮询(降级)8.2 中断丢失中断来了但没处理。原因:中断禁用太久(local_irq_save 时间长)共享中断一个 handler 返回 IRQ_NONE 没轮到下一个中断控制器配置错(threshold 太高屏蔽了)排查:cat /proc/interrupts看计数是否增长ftrace 跟踪 handler 是否被调(16 篇)嵌入式视角:你 I2C_unlock 防死锁的 Linux 版你 [[01-Projects/FB2S/I2C imu死锁问题]] 的 I2C_unlock 防死锁——Linux I2C 子系统也有 timeout/recovery 机制。中断风暴/丢失类似你裸机调中断。方法论同:① 看计数;② 确认清中断;③ 检查触发类型;④ 必要时改轮询。九、注册中断的完整示例(platform 驱动)staticirqreturn_tmy_hardirq(intirq,void*dev_id){structmy_dev*devdev_id;u32 statusreadl(dev-baseIRQ_STATUS);if(!status)returnIRQ_NONE;writel(status,dev-baseIRQ_CLEAR);// 清中断dev-pendingstatus;returnIRQ_WAKE_THREAD;}staticirqreturn_tmy_thread(intirq,void*dev_id){structmy_dev*devdev_id;u32 statusdev-pending;if(statusRX_IRQ){mutex_lock(dev-lock);process_rx(dev);// 可睡mutex_unlock(dev-lock);}if(statusTX_IRQ)process_tx(dev);returnIRQ_HANDLED;}staticintmy_probe(structplatform_device*pdev){structmy_dev*dev;intirq,ret;devdevm_kzalloc(pdev-dev,sizeof(*dev),GFP_KERNEL);dev-basedevm_platform_ioremap_resource(pdev,0);// 从设备树拿中断号irqplatform_get_irq(pdev,0);// 注册 threaded irqretdevm_request_threaded_irq(pdev-dev,irq,my_hardirq,my_thread,IRQF_ONESHOT|IRQF_TRIGGER_FALLING,my_dev,dev);return0;}这是你写 Linux 中断驱动的标准模板devm_request_threaded_irq IRQF_ONESHOT 设备树拿 irq ——新驱动就这么写。devm_前缀是资源管理(自动释放,见 09/11 篇)。你 BSP 写中断驱动,套这模板。十、对照总表概念FreeRTOSRISC-V bare-metalLinux中断号直接(GPIO/向量)PLIC sourcevirq(irq_domain 翻译)中断控制器NVIC/你配PLIC 你配irqchip 驱动封装顶半部ISR你写 trap handlerrequest_irq handler下半部通知任务(FromISR)你写softirq/tasklet/workqueue/threadedISR 能睡❌❌❌(顶半部),✅(workqueue/threaded)清中断你写你写你写(handler 里)共享中断无无IRQF_SHARED中断绑核N/APLIC per-coresmp_affinity注册xInterruptRegister你写request_irq/request_threaded_irq十一、本篇小结中断架构:硬件中断 → entry.S → handle_irq → 顶半部 handler → 下半部irq_domain:hwirq↔virq 翻译层,驱动用 virq,跨平台;irqchip 驱动封装 PLIC/GIC顶半部:硬中断上下文,不能睡不能耗时,只确认拷贝触发下半部下半部三件套:softirq(性能最高,驱动用不到)tasklet(弃用中,别用)workqueue(可睡,常用)threaded irq(现代首选,专属线程可睡可设优先级)中断上下文(硬/软)绝对不能睡,进程上下文(workqueue/threaded)可睡共享中断 IRQF_SHARED;threaded irq 必加 IRQF_ONESHOT中断亲和性smp_affinity绑核;中断风暴/丢失排查看/proc/interrupts新驱动模板:devm_request_threaded_irq IRQF_ONESHOT速查表想干啥用什么注册普通中断request_irq(virq, handler, flags, name, dev)注册可睡中断(首选)devm_request_threaded_irq(…, hardirq, thread_fn, IRQF_ONESHOT|…, …)顶半部触发下半部schedule_work / tasklet_schedule(老)/ return IRQ_WAKE_THREAD可睡下半部workqueue 或 threaded irq中断里分配kmalloc(size, GFP_ATOMIC)中断里持锁spinlock(自旋,不睡)看中断计数cat /proc/interrupts绑核echo mask /proc/irq//smp_affinity看亲和性cat /proc/irq//smp_affinity强制全中断线程化cmdline threadirqs清中断handler 里 writel(IRQ_CLEAR, baseSTATUS)技术之路漫漫分享是为了更好地交流。如果本文的内容对你有启发希望能得到你的点赞 和收藏 ⭐。如果你在调试过程中遇到了其他问题欢迎在评论区 留言我们一起探讨。也欢迎关注 我一起交流底层开发的那些事儿。
延伸阅读

更多相关文章

2026/10/2 17:18:45

vim模式化编辑器详解:从查找与替换到sudo配置实战

1. 别被"怎么退出vim"劝退:先看懂它的模式设计打开终端输入vim,在键盘上敲了几个字母发现全被当成命令执行了,想退出还退不出去,只能按CtrlC碰运气——这是几乎所有vim新手的第一段经历。"怎么退出vim"已经是…

2026/10/2 17:18:45

告别低效写作:AI论文写作软件测评与推荐

2026年真正好用的AI论文写作软件,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 …

2026/10/2 19:23:53

WorkBuddy本地网关:14个免费模型通道自动路由实战

1. 为什么要把十几个免费模型通道塞进一个入口手里攒了一堆免费模型通道的人,大概都经历过这种混乱:写代码的时候想用响应快的,写文案的时候想用文笔好的,做长文档总结的时候又想换一个上下文窗口大的。结果就是浏览器里开着五六个…

2026/10/2 19:23:53

从零手写Agent骨架:LLM工具调用与MCP协议实战入门

1. 为什么我要写这个 AgentSeed 系列 过去大半年,我几乎把市面上能叫得出名字的 Agent 框架都摸了一遍,从最早期用纯 Prompt 拼工具调用,到后来上手各种编排框架,再到自己动手写调度层、写记忆模块、写工具注册中心。踩过的坑多到…

2026/10/2 19:23:53

FastAPI+Vue3构建家教预约平台:从数据模型到并发控制的实战指南

去年帮朋友做了一套基于Python和Vue3的家教预约服务平台,前前后后从需求梳理到上线部署走了两个多月,中间踩了不少坑,也沉淀了一些比较实用的设计经验。这套系统并不是那种纯练手的Demo,而是真正要给学生、家长、家教老师三方一起…

2026/10/2 19:23:53

a2a-alert-agent:Python告警通知封装库的配置与实战指南

最近在搭自动化告警这套东西的时候,我又把那个Python包拎出来用了一遍——a2a-alert-agent。这名字初看有点绕,拆开其实就是agent to alert:给程序配一个“告警通讯员”。脚本跑挂了、指标超阈值了、定时任务静默失败了,它能在第一…

2026/10/2 19:23:53

Redis模糊查询全解析:从KEYS阻塞到SCAN与索引设计实战

如果你在业务代码里写过KEYS user:*,那你大概体会过那种“上线前好好的,一压测 Redis 就报警”的酸爽。Redis 的模糊查询一直是个很矛盾的话题:需求太常见,官方又不推荐用KEYS直接扫。很多人被问到时第一反应是“用 KEYS 不就完了…

2026/10/2 19:18:52

显式状态驱动:为Coding Agent构建可靠Harness执行框架

最近两个月的周末,我基本都泡在一件事上:让 coding agent 在一批真实仓库里稳定地完成“改需求-跑测试-提PR”这个闭环。试了很多方案后,一个在社区里被反复讨论的术语落到了我面前——harness。更确切地说,是 Jev 这个项目背后那…

2026/10/2 8:16:46

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/10/2 18:20:53

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/2 0:02:57

PWN入门:从栈溢出原理到ROP链实战

1. 这不是“学PWN”,是重新理解你每天敲的每一行C代码我第一次在CTF赛场上写出能控制程序流的exp时,手抖得连gdb的c命令都输错三次。那道题只有23行C代码,一个gets()调用,一个printf(),一个return——它甚至没开NX&…

2026/10/2 0:02:57

Windows下cudaMallocHost显存占用之谜:WDDM与TCC模式差异及优化方案

1. 一个反直觉的显存占用现象第一次在 Windows 上看到cudaMallocHost把显存吃掉的时候,我的反应是打开任务管理器反复确认了三遍。明明调用的是主机端锁页内存分配,按 CUDA 文档的说法,这块内存应该落在系统 RAM 里,跟 GPU 的显存…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑