当前位置: 首页 > article >正文

Linux 调度器中的远程抢占:smp_send_reschedule 的实现与应用

一、简介在现代多核处理器架构中对称多处理SMP, Symmetric Multi-Processing已成为服务器、桌面乃至移动设备的标准配置。Linux内核作为支持最广泛硬件平台的操作系统其调度器必须高效地协调多个CPU核心上的任务分配以实现负载均衡、实时响应和能效优化。远程抢占Remote Preemption是Linux调度子系统的核心机制之一。当某个CPU核心源CPU唤醒了一个高优先级任务而该任务的目标运行CPU正在执行低优先级任务时调度器需要一种机制来通知目标CPU立即进行重新调度。这种跨CPU的通知机制正是通过处理器间中断IPI, Inter-Processor Interrupt实现的而smp_send_reschedule就是触发这一远程抢占的关键函数。掌握远程抢占机制对于以下场景至关重要实时系统开发确保硬实时任务在微秒级延迟内得到响应虚拟化性能优化减少vCPU之间的调度延迟如KVM/QEMU环境内核性能调优分析/proc/interrupts中的 Rescheduling Interrupts 统计异构计算在ARM big.LITTLE或Intel hybrid架构中优化任务迁移本文将从源码层面深入解析smp_send_reschedule的实现逻辑通过实际案例演示如何监控和优化远程抢占行为为读者提供可复现的实验环境和调试技巧。二、核心概念2.1 处理器间中断IPIIPI是SMP架构中CPU核心之间通信的基石。与外部设备触发的中断不同IPI由CPU自身通过本地高级可编程中断控制器Local APIC发送给系统中的其他CPU。在Linux内核中IPI主要用于以下场景IPI类型用途处理函数RESCHEDULE_VECTOR触发远程CPU重新调度scheduler_ipi()CALL_FUNCTION_VECTOR请求远程CPU执行指定函数generic_smp_call_function_interrupt()CALL_FUNCTION_SINGLE_VECTOR请求单个远程CPU执行函数generic_smp_call_function_single_interrupt()TLB_SHOOTDOWN_VECTORTLB刷新同步flush_tlb_func()2.2 唤醒抢占Wakeup Preemption当任务从睡眠状态被唤醒时调度器需要决定选择目标CPU通过select_task_rq选择最适合运行该任务的CPU检查抢占条件如果目标CPU正在运行低优先级任务触发抢占同步vs异步唤醒同步唤醒源CPU与目标CPU共享最后一级缓存LLC直接在本地上下文完成唤醒和抢占检查异步唤醒跨缓存域唤醒通过smp_send_reschedule发送IPI在目标CPU的中断上下文中完成后续操作2.3 关键数据结构// include/linux/sched.h struct task_struct { int prio; // 动态优先级 int static_prio; // 静态优先级nice值 const struct sched_class *sched_class; // 调度类 unsigned int policy; // 调度策略SCHED_FIFO/RR/OTHER等 struct sched_entity se; // CFS调度实体 struct sched_rt_entity rt; // RT调度实体 // ... }; // kernel/sched/sched.h struct rq { raw_spinlock_t lock; unsigned int nr_running; // 可运行任务数 struct task_struct *curr; // 当前运行任务 struct task_struct *idle; // idle线程 u64 clock; // 运行队列时钟 // ... };2.4 调度类优先级Linux调度器采用模块化设计调度类按优先级从高到低排列stop_sched_class停止类最高优先级用于任务迁移dl_sched_class截止时间调度类Deadlinert_sched_class实时调度类FIFO/RRfair_sched_class完全公平调度类CFS默认idle_sched_class空闲调度类最低优先级三、环境准备3.1 硬件与软件要求项目最低配置推荐配置CPUx86_64双核或ARM64双核Intel i7/AMD Ryzen 7 或 Apple Silicon M1内存4GB8GB操作系统Linux 5.4Linux 6.1长期支持版内核源码对应版本linux-6.6或更新版本调试工具perf, bpftoolftrace, trace-cmd, kernelshark3.2 内核编译与配置# 1. 下载内核源码 wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.tar.xz tar -xf linux-6.6.tar.xz cd linux-6.6 # 2. 配置内核选项关键配置 make menuconfig # 必须开启的选项 # General setup - [*] Prompt for development and/or incomplete code/drivers # Kernel hacking - Tracers - [*] Kernel Function Tracer # Kernel hacking - Tracers - [*] Schedule tracer # Kernel hacking - Tracers - [*] Enable trace events for preemptirqsoff # General setup - [*] Profiling support # 3. 编译并安装 make -j$(nproc) sudo make modules_install sudo make install # 4. 重启进入新内核 sudo reboot3.3 调试工具安装# Ubuntu/Debian sudo apt-get install linux-tools-common linux-tools-generic trace-cmd kernelshark bpfcc-tools # CentOS/RHEL/Fedora sudo dnf install perf trace-cmd kernelshark bpftools # 验证perf版本 perf --version四、应用场景远程抢占机制在以下具体场景中发挥关键作用场景一高性能网络处理在DPDK或XDPeXpress Data Path应用中网卡中断通常绑定到特定CPU核心。当数据包到达时如果对应的处理线程正在其他核心上睡眠内核需要立即唤醒该线程。若目标核心正在运行低优先级后台任务通过smp_send_reschedule发送的IPI可强制目标核心立即切换上下文确保网络包在微秒级内得到处理避免延迟累积。场景二实时音视频处理在视频会议系统中音频采集线程通常具有实时优先级SCHED_FIFO。当音频缓冲区需要填充时如果该线程被迁移到了正在执行批量压缩任务的核心上远程抢占机制确保音频线程在毫秒级延迟内抢占CPU防止音频卡顿。内核通过检查check_preempt_curr判断实时任务的优先级差异触发跨核心的IPI中断。场景三虚拟化环境中的vCPU调度在KVM虚拟化中每个vCPU对应一个宿主机的任务。当Guest OS中的I/O完成中断到达时如果对应的vCPU线程不在运行状态宿主机的Anubis等调度优化框架会利用smp_send_reschedule机制通过中断重定向和IPI boosting技术将vCPU立即调度到合适的物理核心显著降低I/O延迟。场景四异构多核负载均衡在ARM big.LITTLE架构中高性能核心big与能效核心LITTLE组成异构系统。当轻量级任务突然变为计算密集型时调度器决定将其迁移到big核心。如果目标big核心正在运行低优先级后台任务通过远程抢占IPI通知该核心立即重新调度确保任务迁移的及时性避免性能抖动。五、实际案例与步骤5.1 案例一观察Rescheduling IPI的触发目标通过perf工具监控smp_send_reschedule的调用频率和触发源。# 1. 查看当前系统的IPI统计 cat /proc/interrupts | grep -E (RES|IPI) # 示例输出 # RES: 123456 234567 345678 456789 Rescheduling interrupts # CAL: 1000 2000 3000 4000 Function call interrupts # TLB: 500 600 700 800 TLB shootdowns # 2. 使用perf trace捕获smp_send_reschedule调用 sudo perf trace -e irq_vectors:* -e sched:sched_wakeup* -- sleep 10 # 3. 更精确的跟踪捕获发送和接收端 sudo perf record -e irq_vectors:reschedule_entry \ -e irq_vectors:reschedule_exit \ -e sched:sched_wakeup \ -e sched:sched_switch \ --all-cpus -- sleep 5 # 4. 分析结果 sudo perf report --sortcpu,dso,symbol # 5. 实时监控每2秒刷新 watch -n 2 cat /proc/interrupts | grep RES代码说明/proc/interrupts中的RES行显示每个CPU接收到的Rescheduling IPI数量irq_vectors:reschedule_entry追踪目标CPU接收IPI的入口sched:sched_wakeup追踪任务唤醒事件可与IPI事件关联分析5.2 案例二分析远程抢占的触发条件目标编写内核模块演示try_to_wake_up到smp_send_reschedule的调用链。// remote_preempt_tracer.c // 内核模块追踪远程抢占的触发点 #include linux/module.h #include linux/kprobes.h #include linux/sched.h #include linux/smp.h static struct kprobe kp_ttwu, kp_resched; // 探针1try_to_wake_up入口 static int handler_ttwu(struct kprobe *p, struct pt_regs *regs) { struct task_struct *p_task (struct task_struct *)regs-di; // x86_64参数1 int cpu smp_processor_id(); // 检查是否是远程唤醒目标CPU ! 当前CPU int target_cpu task_cpu(p_task); if (target_cpu ! cpu) { printk(KERN_INFO [TTWU] CPU%d waking up %s[%d] on CPU%d\n, cpu, p_task-comm, p_task-pid, target_cpu); } return 0; } // 探针2smp_send_reschedule入口 static int handler_resched(struct kprobe *p, struct pt_regs *regs) { int target_cpu (int)regs-di; // x86_64参数目标CPU printk(KERN_INFO [RESCHED IPI] CPU%d sending reschedule IPI to CPU%d\n, smp_processor_id(), target_cpu); // 打印当前运行的任务和栈回溯 printk(KERN_INFO Current task: %s[%d]\n, current-comm, current-pid); dump_stack(); // 打印调用栈 return 0; } static int __init tracer_init(void) { int ret; // 设置try_to_wake_up探针 kp_ttwu.symbol_name try_to_wake_up; kp_ttwu.pre_handler handler_ttwu; ret register_kprobe(kp_ttwu); if (ret 0) { pr_err(register_kprobe(twtwu) failed: %d\n, ret); return ret; } // 设置smp_send_reschedule探针 kp_resched.symbol_name smp_send_reschedule; kp_resched.pre_handler handler_resched; ret register_kprobe(kp_resched); if (ret 0) { pr_err(register_kprobe(resched) failed: %d\n, ret); unregister_kprobe(kp_ttwu); return ret; } pr_info(Remote preemption tracer loaded\n); return 0; } static void __exit tracer_exit(void) { unregister_kprobe(kp_ttwu); unregister_kprobe(kp_resched); pr_info(Remote preemption tracer unloaded\n); } module_init(tracer_init); module_exit(tracer_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(Linux Kernel Developer); MODULE_DESCRIPTION(Trace remote preemption via IPI);Makefile# Makefile for remote_preempt_tracer.ko KDIR ? /lib/modules/$(shell uname -r)/build PWD : $(shell pwd) obj-m remote_preempt_tracer.o all: make -C $(KDIR) M$(PWD) modules clean: make -C $(KDIR) M$(PWD) clean load: sudo insmod remote_preempt_tracer.ko sudo dmesg -c unload: sudo rmmod remote_preempt_tracer sudo dmesg编译与测试# 编译模块 make # 加载模块 sudo insmod remote_preempt_tracer.ko # 生成负载创建跨CPU唤醒的场景 # 终端1绑定到CPU0运行高优先级任务 sudo taskset -c 0 sh -c while :; do :; done PID1$! # 终端2绑定到CPU1唤醒CPU0上的任务 sudo taskset -c 1 bash -c for i in {1..10}; do # 向CPU0上的任务发送信号触发唤醒 kill -CONT $PID1 usleep 100000 done # 查看日志 sudo dmesg | grep -E (TTWU|RESCHED) # 清理 kill $PID1 sudo rmmod remote_preempt_tracer5.3 案例三理解scheduler_ipi的处理流程目标分析目标CPU接收IPI后的处理逻辑。# 使用ftrace跟踪scheduler_ipi的执行 sudo trace-cmd start -p function_graph -l scheduler_ipi -l sched_ttwu_pending # 运行负载测试 stress-ng --cpu 4 --timeout 10s # 停止跟踪并查看结果 sudo trace-cmd stop sudo trace-cmd report | head -100 # 更详细的跟踪包含try_to_wake_up相关函数 sudo trace-cmd start -p function_graph \ -g try_to_wake_up \ -g scheduler_ipi \ -g smp_send_reschedule # 查看图形化输出 sudo trace-cmd report -G | less关键代码路径分析基于Linux 6.6内核// kernel/sched/core.c /* * scheduler_ipi - 处理远程CPU发送的reschedule IPI * * 这是异步唤醒的下半部分在目标CPU的中断上下文中执行 */ void scheduler_ipi(void) { /* * 必须禁用中断因为我们正在操作Per-CPU的wake_list */ irq_enter_rcu(); /* * 处理pending的唤醒任务 * 这些任务由其他CPU通过ttwu_queue_remote加入 */ sched_ttwu_pending(); /* * 检查是否需要重新调度 * 如果TIF_NEED_RESCHED被设置则在irq_exit时触发调度 */ irq_exit_rcu(); } /* * sched_ttwu_pending - 处理唤醒队列中的任务 */ static void sched_ttwu_pending(void) { struct rq *rq this_rq(); struct llist_node *llist llist_del_all(rq-wake_list); struct task_struct *p, *t; // 遍历所有pending的唤醒任务 llist_for_each_entry_safe(p, t, llist, wake_entry) { // 将任务激活并加入运行队列 ttwu_do_activate(rq, p, p-wake_flags, ENQUEUE_NOCLOCK); } } /* * ttwu_do_activate - ttwu_do_wakeup - check_preempt_curr * 最终检查是否需要抢占当前运行任务 */ static void ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags) { // 检查是否触发唤醒抢占 check_preempt_curr(rq, p, wake_flags); // 如果被唤醒的是高优先级任务设置TIF_NEED_RESCHED if (p-sched_class ! rq-curr-sched_class || p-prio rq-curr-prio) { resched_curr(rq); } }5.4 案例四x86_64架构的IPI发送实现目标深入arch/x86/kernel/smp.c了解硬件层面的IPI发送机制。// arch/x86/kernel/smp.c /* * smp_send_reschedule - 向指定CPU发送重新调度IPI * cpu: 目标CPU * * 这是架构相关的实现通过Local APIC发送IPI */ void smp_send_reschedule(int cpu) { // 调用native_smp_send_reschedule非虚拟化环境 if (likely(x86_platform_ipi_callback NULL)) { apic-send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR); } else { // 虚拟化环境如Xen的特殊处理 x86_platform_ipi_callback(cpu); } } /* * native_smp_send_reschedule - 原生x86实现 * 通过写APIC的ICRInterrupt Command Register寄存器发送IPI */ static inline void __default_send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest) { u32 cfg; // 构造ICR值包含目标CPU掩码和向量号 cfg __prepare_ICR(mask, vector, dest); // 写入ICR寄存器触发硬件IPI native_apic_mem_write(APIC_ICR, cfg); } // ICR寄存器位定义arch/x86/include/asm/apicdef.h #define APIC_ICR_VECTOR 0x000000FF // 向量号0-255 #define APIC_ICR_DEST_MASK 0x00000000 // 目标模式 #define APIC_ICR_DEST_FIELD 0x000C0000 // 目标字段 #define APIC_ICR_SEND_PENDING 0x00001000 // 发送状态位验证ICR寄存器写入# 使用msr-tools读取APIC相关MSR需root权限 sudo modprobe msr # 读取x2APIC ICR寄存器MSR 0x830 sudo rdmsr -p 0 0x830 # CPU0的ICR sudo rdmsr -p 1 0x830 # CPU1的ICR # 注意直接读取可能显示0因为ICR是只写寄存器发送后立即清除 # 更好的方法是通过tracepoints跟踪 sudo perf trace -e msr:* -- sleep 5六、常见问题与解答Q1: 为什么/proc/interrupts中Rescheduling interrupts数值很高是否表示系统有问题A: 不一定。Rescheduling interrupts高通常表示高并发场景大量任务在多核间迁移调度器频繁进行负载均衡实时任务活跃实时任务频繁唤醒触发跨核抢占电源管理系统频繁进入/退出空闲状态C-states唤醒时触发IPI诊断方法# 检查是否是特定进程导致 sudo perf top -e irq_vectors:reschedule_entry # 查看调度延迟 sudo perf sched latency # 如果数值异常高如每秒数万次检查BIOS设置或禁用C-states sudo cpupower idle-set -D # 禁用所有空闲状态进行测试Q2:smp_send_reschedule和resched_curr有什么区别A: 关键区别如下函数调用场景执行位置是否发送IPIresched_curr本地或远程CPU需要重新调度任意上下文仅当目标CPU≠当前CPU且非idle polling时smp_send_reschedule专门用于远程CPU通知任意上下文总是发送IPI通过APIC调用关系resched_curr(struct rq *rq) - if (cpu ! smp_processor_id()) - if (set_nr_and_not_polling(curr)) - smp_send_reschedule(cpu) // 触发IPIQ3: 如何减少不必要的Rescheduling IPIA: 优化策略包括# 1. 使用taskset绑定关键任务到特定CPU减少跨核迁移 sudo taskset -c 0 ./high_priority_task # 2. 调整调度域参数减少负载均衡频率 sudo sysctl kernel.sched_migration_cost_ns500000 # 默认500000ns # 3. 对于实时任务使用SCHED_FIFO并绑定CPU sudo chrt -f 99 taskset -c 1 ./rt_task # 4. 在虚拟化环境中使用virtio-blk/dataplane减少IPI # 配置vCPU pinning避免vCPU在物理核间跳动Q4: 为什么ARM架构的scheduler_ipi实现与x86不同A: 主要差异源于中断控制器架构x86: 使用Local APICIPI通过写MSR/内存映射寄存器发送向量号0x20-0xFF可自定义ARM: 使用GICGeneric Interrupt ControllerSGISoftware Generated Interrupt0-15用于IPI其中SGI 0通常分配给rescheduleARM64代码片段// arch/arm64/kernel/smp.c void smp_send_reschedule(int cpu) { // 通过GIC发送SGISoftware Generated Interrupt // RESCHEDULE_IPI通常映射到SGI 0 gic_send_sgi(cpu, RESCHEDULE_IPI); }Q5: 如何调试IPI丢失或延迟问题A: 使用trace-cmd捕获完整调度链# 1. 启用所有相关tracepoints sudo trace-cmd start -e sched:sched_wakeup -e sched:sched_switch \ -e irq_vectors:reschedule_entry -e irq_vectors:reschedule_exit \ -e sched:sched_migrate_task # 2. 复现问题场景 ./workload_generator # 3. 分析延迟 sudo trace-cmd report -t -l sched_wakeup,sched_switch,reschedule_entry | \ awk /sched_wakeup.*target_cpu1/ { start$1 } /reschedule_entry.*cpu1/ { end$1; print Delay: (end-start)/1000 us } # 4. 使用kernelshark图形化分析 sudo kernelshark trace.dat七、实践建议与最佳实践7.1 性能优化建议1. 减少跨NUMA节点的远程抢占 跨NUMA节点的IPI需要经过互联网络如Intel UPI/AMD Infinity Fabric延迟远高于同NUMA节点。优化策略// 在应用层使用numactl绑定内存和CPU // numactl --membind0 --cpunodebind0 ./application // 在内核模块中检查NUMA节点 int src_nid cpu_to_node(src_cpu); int dst_nid cpu_to_node(dst_cpu); if (src_nid ! dst_nid) { // 避免跨NUMA唤醒除非必要 dst_cpu find_cpu_in_node(src_nid, p); }2. 批量处理IPI 现代x86支持IPI multicast通过APIC的cluster模式但Linux内核默认使用点对点发送。在高频唤醒场景下考虑合并多个唤醒请求// 伪代码批量发送IPI void smp_send_reschedule_batch(cpumask_t *mask) { if (cpumask_weight(mask) 1 x2apic_enabled()) { // 使用cluster模式批量发送如果硬件支持 apic-send_IPI_cluster(mask, RESCHEDULE_VECTOR); } else { // 回退到逐个发送 for_each_cpu(cpu, mask) smp_send_reschedule(cpu); } }3. 避免idle polling时的IPI 当目标CPU处于idle状态且正在轮询时无需发送IPI直接设置标志位即可// kernel/sched/core.c: resched_curr if (set_nr_and_not_polling(curr)) smp_send_reschedule(cpu); else trace_sched_wake_idle_without_ipi(cpu);7.2 调试技巧使用BPF跟踪IPI延迟// reschedule_latency.bpf.c // 使用eBPF跟踪IPI发送和接收的延迟 #include linux/bpf.h #include linux/sched.h #include bpf/bpf_helpers.h #include bpf/bpf_tracing.h struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1024); __type(key, u32); // CPU pair (src 16 | dst) __type(value, u64); // timestamp } ipi_send_map; SEC(kprobe/smp_send_reschedule) int BPF_KPROBE(trace_send, int cpu) { u32 key ((u32)smp_processor_id() 16) | (u32)cpu; u64 ts bpf_ktime_get_ns(); bpf_map_update_elem(ipi_send_map, key, ts, BPF_ANY); return 0; } SEC(kprobe/scheduler_ipi) int BPF_KPROBE(trace_recv) { u32 cpu bpf_get_smp_processor_id(); // 遍历map查找发送到这个CPU的IPI // ... 计算并记录延迟 return 0; } char LICENSE[] SEC(license) GPL;编译和运行# 使用libbpf或bcc编译 clang -O2 -target bpf -c reschedule_latency.bpf.c -o reschedule_latency.o # 加载BPF程序 sudo bpftool prog load reschedule_latency.o /sys/fs/bpf/reschedule_latency # 查看输出 sudo cat /sys/kernel/debug/tracing/trace_pipe7.3 内核配置优化针对特定工作负载调整调度参数# /etc/sysctl.conf 或 /proc/sys/kernel/ # 增加实时任务运行时间us kernel.sched_rt_runtime_us 950000 kernel.sched_rt_period_us 1000000 # 减少负载均衡开销ns kernel.sched_migration_cost_ns 250000 # 默认500000 kernel.sched_nr_migrate 32 # 默认32 # 禁用不必要的调度统计生产环境 CONFIG_SCHEDSTATSn八、总结与应用场景8.1 核心要点回顾本文深入剖析了Linux调度子系统中的远程抢占机制核心要点包括触发条件当高优先级任务被唤醒且目标CPU运行低优先级任务时通过check_preempt_curr判断需要远程抢占IPI机制smp_send_reschedule通过Local APICx86或GICARM向目标CPU发送RESCHEDULE_VECTOR中断异步处理目标CPU在scheduler_ipi中断处理程序中完成任务的实际唤醒和抢占检查减少跨CPU锁竞争架构差异x86使用APIC ICR寄存器ARM使用GIC SGI但上层语义一致8.2 实战必要性掌握远程抢占机制对于以下领域至关重要实时LinuxPREEMPT_RT硬实时任务要求确定性延迟必须理解IPI对调度延迟的影响云原生虚拟化Kubernetes Kata Containers环境下vCPU调度直接影响容器响应时间异构计算ARM big.LITTLE、Intel Alder Lake等架构需要精细的跨核调度策略性能分析解释/proc/interrupts中Rescheduling interrupts异常定位惊群问题8.3 未来演进随着硬件发展远程抢占机制也在演进Intel User IPIUIPI用户态直接发送IPI减少内核态开销AMD AVIC虚拟化环境下的高级虚拟中断控制器优化vCPU IPIARM GICv4支持直接注入虚拟中断减少VM退出建议读者结合kernel/sched/core.c、arch/x86/kernel/smp.c源码使用本文提供的BPF和trace-cmd工具在实际系统上观察远程抢占行为深化理解。参考文献Linux Kernel Source: kernel/sched/core.c, arch/x86/kernel/smp.c (v6.6)Linux Device Driver Development, 2nd Edition - Chapter on IPI handlingMaking Kernel Bypass Practical for the Cloud with Junction - NSDI24Maximizing VMs IO Performance on Overcommitted CPUs with Fairness

相关文章:

Linux 调度器中的远程抢占:smp_send_reschedule 的实现与应用

一、简介在现代多核处理器架构中,对称多处理(SMP, Symmetric Multi-Processing) 已成为服务器、桌面乃至移动设备的标准配置。Linux内核作为支持最广泛硬件平台的操作系统,其调度器必须高效地协调多个CPU核心上的任务分配&#xf…...

Subnautica Nitrox:在深海孤独中点亮协作的灯塔

Subnautica Nitrox:在深海孤独中点亮协作的灯塔 【免费下载链接】Nitrox An open-source, multiplayer modification for the game Subnautica. 项目地址: https://gitcode.com/gh_mirrors/ni/Nitrox 当450米深的幽暗海水包裹着你的潜水服,周围只…...

Windows Defender Remover终极指南:高效移除系统防护的完整方案

Windows Defender Remover终极指南:高效移除系统防护的完整方案 【免费下载链接】windows-defender-remover A tool which is uses to remove Windows Defender in Windows 8.x, Windows 10 (every version) and Windows 11. 项目地址: https://gitcode.com/gh_mi…...

小白也能懂!ERNIE-4.5-0.3B-PT部署实战:从环境配置到Web界面调用

小白也能懂!ERNIE-4.5-0.3B-PT部署实战:从环境配置到Web界面调用 1. 为什么选择ERNIE-4.5-0.3B-PT 如果你正在寻找一个既轻量又强大的中文文本生成模型,ERNIE-4.5-0.3B-PT绝对值得考虑。这个只有3亿参数的模型,在中文理解和生成…...

别再只用编码器了!用ROS的robot_localization包融合IMU与Odom,让你的Cartographer建图精度翻倍

突破SLAM精度瓶颈:robot_localization包在Cartographer中的实战优化指南 当你的移动机器人在长走廊环境中反复建图却始终无法对齐首尾时,当激光匹配在特征稀疏区域频繁出现定位跳变时,这些现象很可能源于单一编码器里程计的累积误差。本文将带…...

Flink项目实战篇 基于Flink的智慧交通实时预警系统(上)

1. 项目背景与核心需求 想象一下早晚高峰时段的城市主干道,密密麻麻的车流像蜗牛一样缓慢移动。交警指挥中心的大屏幕上,红色拥堵区域不断扩散,却无法快速定位问题根源。这正是传统交通管理面临的痛点——数据滞后和响应迟缓。而我们的智慧交…...

postgresql QueryWrapper left join

原生的 MyBatis-Plus QueryWrapper 不支持 LEFT JOIN。QueryWrapper 的设计初衷是用于单表的 CRUD 操作。它生成的 SQL 结构固定为 SELECT ... FROM table WHERE ...,无法直接生成 JOIN 子句。但是,如果你需要在 MyBatis-Plus 中实现联查(特别…...

零基础入门《Natural Language Processing with PyTorch》中文翻译项目手把手教程

零基础入门《Natural Language Processing with PyTorch》中文翻译项目手把手教程 【免费下载链接】nlp-pytorch-zh 《Natural Language Processing with PyTorch》中文翻译 项目地址: https://gitcode.com/gh_mirrors/nl/nlp-pytorch-zh 《Natural Language Processing…...

漏洞扫描系统毕业设计:基于任务队列与异步调度的效率优化实践

在计算机安全领域,漏洞扫描系统是评估网络资产安全性的重要工具。对于计算机专业的同学来说,将其作为毕业设计选题,既能综合运用网络、数据库、并发编程等知识,又能接触到安全领域的核心实践。然而,一个初版的扫描系统…...

从检测到理解:构建基于YOLOv5、DeepSORT与SlowFast的智能视频行为分析引擎

1. 为什么需要智能视频行为分析? 想象一下这样的场景:超市保安需要盯着几十个监控屏幕,试图从人群中找出可疑行为;幼儿园老师要时刻关注每个孩子的活动,防止意外发生。传统监控完全依赖人力,不仅效率低下&a…...

Citrix敦促用户修补允许未认证数据泄露的关键NetScaler漏洞

Citrix已发布安全更新,修复NetScaler ADC和NetScaler Gateway中的两个漏洞,其中包括一个可能被利用泄露应用程序敏感数据的关键缺陷。漏洞详情如下:CVE-2026-3055(CVSS评分:9.3)- 输入验证不足导致内存越界…...

【技术实践解析】SAM-Adapter:如何让“分割一切”模型在特定场景下表现更佳

1. 为什么需要SAM-Adapter? 当你第一次听说"分割一切"的SAM模型时,可能会觉得这简直是计算机视觉领域的"万能钥匙"。确实,Meta发布的Segment Anything Model(SAM)在通用图像分割任务上表现惊艳&am…...

nli-distilroberta-base惊艳效果:中英文混合句子对推理准确率超89.2%

nli-distilroberta-base惊艳效果:中英文混合句子对推理准确率超89.2% 1. 项目概述 nli-distilroberta-base是基于DistilRoBERTa模型的自然语言推理(NLI)Web服务,专门用于判断两个句子之间的逻辑关系。这个轻量级模型在保持高性能的同时,大幅…...

告别手动转录烦恼:BiliBiliCCSubtitle智能工具让视频字幕高效提取成为现实

告别手动转录烦恼:BiliBiliCCSubtitle智能工具让视频字幕高效提取成为现实 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 你是否曾在学习B站教程时&a…...

SpringBoot仓库管理系统毕设实战:从需求建模到高可用部署

最近在帮学弟学妹们看毕业设计,发现很多“仓库管理系统”项目虽然功能齐全,但代码结构混乱,像是把各种技术简单堆砌在一起,离“工程化”和“真实可用”还有不小距离。刚好我之前参与过一个类似的实战项目,今天就来聊聊…...

Ubuntu 20.04 下 COLMAP 编译安装:从 CUDA 架构到依赖冲突的避坑指南

1. 为什么选择源码编译COLMAP? 很多刚接触三维重建的朋友可能会问:为什么不用apt直接安装COLMAP?我在实际项目中发现,Ubuntu官方仓库的版本往往落后于GitHub主线版本2-3个迭代。比如当前Ubuntu 20.04仓库提供的是3.6版&#xff0c…...

Paging3深度实战:如何构建高性能Android分页加载架构

Paging3深度实战:如何构建高性能Android分页加载架构 【免费下载链接】AndroidX-Jetpack-Practice 本仓库致力于建立最全、最新的的 AndroidX Jetpack 相关组件的实践项目 以及组件对应的分析文章(持续更新中)如果对你有帮助,请在…...

安卓 Androidstudio跑步俱乐部管理系统 足球俱乐部app

目录需求分析与功能规划技术选型与架构设计开发流程与里程碑测试与部署策略维护与迭代方向项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作需求分析与功能规划 目标用户:足球俱乐部管理员、教练、球员及家长&#x…...

CocosCreator对话系统实战:从零构建高可维护的剧情交互模块

在游戏开发中,剧情对话系统是连接玩家与游戏世界的重要桥梁。无论是RPG、AVG还是带有叙事元素的休闲游戏,一个流畅、灵活且易于维护的对话系统都至关重要。然而,很多开发者在初次尝试用CocosCreator构建对话系统时,往往会陷入一些…...

《风爆远征英雄年代怀旧服》官方网站:3月25日开服,老玩家直呼爷青回的经典国战

风爆远征英雄年代怀旧服终于定档3月25日开服,不少老玩家翻遍全网找攻略,就怕错过当年热血战场,也怕新版魔改丢了原味,这份走心攻略帮你快速吃透开服要点。《风爆远征英雄年代怀旧服》已正式开启全平台公测,由游昕官方运…...

Kaetram-Open:构建2D MMORPG的开源引擎框架 | 开发者的多人游戏开发解决方案

Kaetram-Open:构建2D MMORPG的开源引擎框架 | 开发者的多人游戏开发解决方案 【免费下载链接】Kaetram-Open Kaetram is an open-source 2D HTML5 MMORPG. It is an extended version of BrowserQuest (BQ). 项目地址: https://gitcode.com/gh_mirrors/ka/Kaetram…...

4步搞定RealSense SR300相机Ubuntu连接:Python深度相机开发终极指南

4步搞定RealSense SR300相机Ubuntu连接:Python深度相机开发终极指南 【免费下载链接】librealsense Intel RealSense™ SDK 项目地址: https://gitcode.com/GitHub_Trending/li/librealsense 你是否在Ubuntu 22.04系统上为RealSense SR300相机的Python连接而…...

如何用TileLang实现高性能GPU算子:从入门到精通的完整指南

如何用TileLang实现高性能GPU算子:从入门到精通的完整指南 【免费下载链接】tilelang Domain-specific language designed to streamline the development of high-performance GPU/CPU/Accelerators kernels 项目地址: https://gitcode.com/GitHub_Trending/ti/…...

若依框架深度定制实战:从模块设计到企业级应用优化

1. 若依框架企业级定制入门指南 第一次接触若依框架时,我就被它"开箱即用"的特性惊艳到了。这个基于Spring Boot和MyBatis的快速开发平台,确实能帮开发者节省大量重复劳动。但真正把它用进企业级项目时,我发现原版框架就像毛坯房&a…...

2024最新版QQNT防撤回插件技术指南:保护您的消息不被删除

2024最新版QQNT防撤回插件技术指南:保护您的消息不被删除 【免费下载链接】LiteLoaderQQNT-Anti-Recall LiteLoaderQQNT 插件 - QQNT 简易防撤回 项目地址: https://gitcode.com/gh_mirrors/li/LiteLoaderQQNT-Anti-Recall 在日常使用QQNT的过程中&#xff0…...

AI英语单词APP的开发

与口语APP强调“实时交互”不同,AI英语单词APP的核心逻辑在于“记忆科学与生成式内容的深度融合”。在2026年,开发重点已从单纯的“数字化单词书”转向“千人千面的动态语境构建”。1. 核心技术架构与链路语义向量引擎 (Vector Embeddings): …...

OG 488 DBCO,俄勒冈绿488 二苯并环辛炔,实现对含叠氮基生物分子的特异性标记

一.名称英文名称:OG 488 DBCO,Oregon Green 488 DBCO中文名称:俄勒冈绿488 二苯并环辛炔激发Ex:496nm发射Em:524nm结构式:二.产品形式1.固体/粉末2.溶于大部分有机溶剂,溶于水3.端基取代率95%4.…...

Flag入门—Flag在返回包中

好靶场简介 漏洞复现学习由"好靶场“支持 官网链接-好靶场平台-安全靶场-网络安全靶场 前期准备 我们开启靶场先看描述 这道题的描述是:”考验你会不会用F12以及Burp抓返回包了“ 如果有能力可以不看描述直接搞 下方开启靶场 靶场开启后我们访问靶场给…...

1801181-54-3,Oregon Green Alkyne,在长时间光照下抗淬灭能力远优于传统荧光素

一.名称中文名称:俄勒冈绿 488 炔基英文名称:OG 488 Alkyne,OG 488 Alk,Oregon Green Alkyne,Oregon Green AlkCAS:1801181-54-3分子式:C24H13F2NO6分子量:449.37激发波长&#xff0…...

伏羲天气预报开放科学:复现代码、数据、环境全公开,推动可重复研究

伏羲天气预报开放科学:复现代码、数据、环境全公开,推动可重复研究 天气预报,这个与每个人生活息息相关的领域,正经历着一场由人工智能驱动的深刻变革。传统的数值天气预报模型虽然精度高,但计算成本巨大,…...