liburing和Linux io_uring源码阅读

探索Linux下高性能异步I/O:用liburing实现的Echo服务器 阅读详情
liburing
版本

系统内核版本: Linux 5.15.0-107-generic #117~20.04.1-Ubuntu x86_64 GNU/Linux

源代码版本: git@github.com:torvalds/linux.git v5.15

阅读入口

从最简单的代码看起,即阅读入口:examples/io_uring-test.c
此源文件内部调用liburing相关函数包含
io_uring_queue_init、io_uring_get_sqe、io_uring_prep_readv、io_uring_submit、io_uring_wait_cqe、io_uring_cqe_seen、io_uring_queue_exit
内核提供的函数仅有三个:io_uring_setup@425、io_uring_enter@426、io_uring_register@427
其中io_uring_queue_init调用的内核函数为io_uring_setup
以此为起点,阅读内核代码。

liburing调用栈
// 示例程序调用代码
struct io_uring_params p;
memset(&p, 0, sizeof(p));
p.flags = 0;
struct io_uring ring;
io_uring_queue_init_params(64, &ring, &p);
int io_uring_queue_init_params(unsigned entries, struct io_uring *ring,
                               struct io_uring_params *p)
{
    int ret;

    ret = io_uring_queue_init_try_nosqarr(entries, ring, p, NULL, 0);
    return ret >= 0 ? 0 : ret;
}
static int io_uring_queue_init_try_nosqarr(unsigned entries, struct io_uring *ring,
                                           struct io_uring_params *p, void *buf,
                                           size_t buf_size)
{
    unsigned flags = p->flags;
    int ret;

    // 重点在__io_uring_queue_init_params函数
    p->flags |= IORING_SETUP_NO_SQARRAY;
    ret = __io_uring_queue_init_params(entries, ring, p, buf, buf_size);

    // 5.15内核不支持IORING_SETUP_NO_SQARRAY, 故会返回 -EINVAL
    // 所以真正执行的是下面的__io_uring_queue_init_params
    if (ret != -EINVAL || (flags & IORING_SETUP_NO_SQARRAY))
        return ret;

    p->flags = flags;
    return __io_uring_queue_init_params(entries, ring, p, buf, buf_size);
}
int __io_uring_queue_init_params(unsigned entries, struct io_uring *ring,
                                 struct io_uring_params *p, void *buf,
                                 size_t buf_size)
{
    int fd, ret = 0;
    unsigned *sq_array;
    unsigned sq_entries, index;

    memset(ring, 0, sizeof(*ring));

    // 省去一些无法走到的代码
    fd = __sys_io_uring_setup(entries, p);
    if (fd < 0) {
        return fd;
    }

    return fd
}

从__sys_io_uring_setup进入内核代码

// 根据调用号425找到函数地址 io_uring_setup
// grep -rn "SYSCALL_DEFINE" $(find ./ -name '*.c')
static long io_uring_setup(u32 entries, struct io_uring_params __user *params)
{
    struct io_uring_params p;
    int i;

    // 将数据从用户空间拷贝到内核空间
    if (copy_from_user(&p, params, sizeof(p)))
        return -EFAULT;
    for (i = 0; i < ARRAY_SIZE(p.resv); i++) {
        if (p.resv[i])
            return -EINVAL;
    }

    if (p.flags & ~(IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL |
                    IORING_SETUP_SQ_AFF | IORING_SETUP_CQSIZE |
                    IORING_SETUP_CLAMP | IORING_SETUP_ATTACH_WQ |
                    IORING_SETUP_R_DISABLED))
        return -EINVAL;

    return io_uring_create(entries, &p, params);
}

由于io_uring_create篇幅过长,走不到的地方将会对其进行裁剪

static int io_uring_create(unsigned entries, struct io_uring_params *p,
                           struct io_uring_params *params)
{
    // p为内核空间地址数据
    // params为用户空间地址数据

    struct io_ring_ctx *ctx;
    struct file *file;
    int ret;

    // 此处检查提交队列SQ大小是否会超过最大限制IORING_MAX_ENTRIES(0x8000)
    if (entries > IORING_MAX_ENTRIES) {
        if (!(p->flags & IORING_SETUP_CLAMP))
            return -EINVAL;
        entries = IORING_MAX_ENTRIES;
    }

    // 保证队列容量是2的幂次方
    p->sq_entries = roundup_pow_of_two(entries);
    // 完成队列CQ是提交队列容量的两倍
    p->cq_entries = 2 * p->sq_entries;

    // 初始化io_ring_ctx对象
    ctx = io_ring_ctx_alloc(p);
    if (!ctx)
        return -ENOMEM;
    ctx->compat = in_compat_syscall();
    if (!capable(CAP_IPC_LOCK))
        ctx->user = get_uid(current_user());

    mmgrab(current->mm);
    ctx->mm_account = current->mm;

    // 申请ctx->rings和ctx->sq_sqes内存
    ret = io_allocate_scq_urings(ctx, p);
    if (ret)
        goto err;

    // 设置了轮询后创建轮询线程函数, 由于参数未设置, 不在展开
    ret = io_sq_offload_create(ctx, p);
    if (ret)
        goto err;

    ret = io_rsrc_node_switch_start(ctx);
    if (ret)
        goto err;
    io_rsrc_node_switch(ctx, NULL);

    // 保存结构体成员偏移地址
    // 用于用户空间创建内存映射时获取到偏移地址, 将用户空间结构体内部变量和内核空间结构体内部变量一一对应
    // liburing io_uring_setup_ring_pointers
    memset(&p->sq_off, 0, sizeof(p->sq_off));
    /**
     * 由于代码中设置了按照cacheline字节对齐
     * 所以p->sq_off.tail = 64, 即虽然head是4字节, 但为了防止`错误共享`, 让其占据一个cacheline大小
     * cacheline一般为64, 也可能是128, 博主PC是64的
     * 错误共享知识可查看
     * https://github.com/TonyBeen/study/blob/master/false_sharing/false_sharing.cc
     * 
     * struct io_uring {
     *     u32 head __attribute__((__aligned__(64)));
     *     u32 tail __attribute__((__aligned__(64)));
     * };
     */
    p->sq_off.head = offsetof(struct io_rings, sq.head);                    // 0
    p->sq_off.tail = offsetof(struct io_rings, sq.tail);                    // 64
    p->sq_off.ring_mask = offsetof(struct io_rings, sq_ring_mask);          // 256
    p->sq_off.ring_entries = offsetof(struct io_rings, sq_ring_entries);    // 264
    p->sq_off.flags = offsetof(struct io_rings, sq_flags);                  // 276
    p->sq_off.dropped = offsetof(struct io_rings, sq_dropped);              // 272
    /**
     * 具体细节在函数io_allocate_scq_urings内部, 如下
     * 下面介绍如何计算得到2368的(代码在rings_size中)
     *
     * sizeof(struct io_rings) = 320 (64字节对齐结果)
     * sizeof(struct io_uring_cqe) = 16
     * cq_entries = 128
     * 
     * p->sq_off.array = cq_entries * sizeof(struct io_uring_cqe) + sizeof(struct io_rings)
     * 得到结果满足在cacheline字节边界上, 不满足的情况下不会是2368
     * 
     */
    p->sq_off.array = (char *)ctx->sq_array - (char *)ctx->rings;           // 2368

    memset(&p->cq_off, 0, sizeof(p->cq_off));
    p->cq_off.head = offsetof(struct io_rings, cq.head);
    p->cq_off.tail = offsetof(struct io_rings, cq.tail);
    p->cq_off.ring_mask = offsetof(struct io_rings, cq_ring_mask);
    p->cq_off.ring_entries = offsetof(struct io_rings, cq_ring_entries);
    p->cq_off.overflow = offsetof(struct io_rings, cq_overflow);
    p->cq_off.cqes = offsetof(struct io_rings, cqes);
    p->cq_off.flags = offsetof(struct io_rings, cq_flags);

    p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP |
                  IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS |
                  IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL |
                  IORING_FEAT_POLL_32BITS | IORING_FEAT_SQPOLL_NONFIXED |
                  IORING_FEAT_EXT_ARG | IORING_FEAT_NATIVE_WORKERS |
                  IORING_FEAT_RSRC_TAGS;

    // 拷贝到用户空间
    if (copy_to_user(params, p, sizeof(*p))) {
        ret = -EFAULT;
        goto err;
    }

    // 以下是创建一个匿名 inode, 并将文件描述符返回
    // 可通过ll /proc/{pid}/fd/ 查看到io_uring的文件描述 3 -> 'anon_inode:[io_uring]'
    // 用户可通过返回文件描述符进行mmap, 以获取对SQ/CQ的内存访问
    file = io_uring_get_file(ctx);
    if (IS_ERR(file)) {
        ret = PTR_ERR(file);
        goto err;
    }

    /*
     * Install ring fd as the very last thing, so we don't risk someone
     * having closed it before we finish setup
     */
    ret = io_uring_install_fd(ctx, file);
    if (ret < 0) {
        /* fput will clean it up */
        fput(file);
        return ret;
    }

    trace_io_uring_create(ret, ctx, p->sq_entries, p->cq_entries, p->flags);
    return ret;
err:
    io_ring_ctx_wait_and_kill(ctx);
    return ret;
}
static int io_allocate_scq_urings(struct io_ring_ctx *ctx,
                                  struct io_uring_params *p)
{
    struct io_rings *rings;
    size_t size, sq_array_offset;

    /* make sure these are sane, as we already accounted them */
    ctx->sq_entries = p->sq_entries;
    ctx->cq_entries = p->cq_entries;

    // rings_size计算的是一块存储struct io_rings + struct io_uring_cqe + sq_array的连续内存
    // sq_array是ctx->sq_sqes的索引数组, 内存大小 = p->sq_entries * sizeof(u32) = 256
    // sq_array_offset = 2368
    // size = 2368 + 256 = 2624
    size = rings_size(p->sq_entries, p->cq_entries, &sq_array_offset);
    if (size == SIZE_MAX)
        return -EOVERFLOW;

    rings = io_mem_alloc(size);
    if (!rings)
        return -ENOMEM;

    ctx->rings = rings;
    ctx->sq_array = (u32 *)((char *)rings + sq_array_offset);
    rings->sq_ring_mask = p->sq_entries - 1;
    rings->cq_ring_mask = p->cq_entries - 1;
    rings->sq_ring_entries = p->sq_entries;
    rings->cq_ring_entries = p->cq_entries;

    size = array_size(sizeof(struct io_uring_sqe), p->sq_entries);
    if (size == SIZE_MAX) {
        io_mem_free(ctx->rings);
        ctx->rings = NULL;
        return -EOVERFLOW;
    }

    ctx->sq_sqes = io_mem_alloc(size);
    if (!ctx->sq_sqes) {
        io_mem_free(ctx->rings);
        ctx->rings = NULL;
        return -ENOMEM;
    }

    return 0;
}

返回用户空间

int __io_uring_queue_init_params(unsigned entries, struct io_uring *ring,
                                 struct io_uring_params *p, void *buf,
                                 size_t buf_size)
{
    int fd, ret = 0;
    unsigned *sq_array;
    unsigned sq_entries, index;

    memset(ring, 0, sizeof(*ring));

    // 省去一些无法走到的代码
    fd = __sys_io_uring_setup(entries, p);
    if (fd < 0) {
        return fd;
    }

    // ------> 从此处执行 <------
    // 未设置IORING_SETUP_NO_MMAP(不使用内存映射)标志
    if (!(p->flags & IORING_SETUP_NO_MMAP)) {
        // io_uring_queue_mmap透传, 直接看io_uring_mmap
        ret = io_uring_queue_mmap(fd, p, ring);
        if (ret) {
            __sys_close(fd);
            return ret;
        }
    }

    return ret;
}
static int io_uring_mmap(int fd, struct io_uring_params *p,
                         struct io_uring_sq *sq, struct io_uring_cq *cq)
{
    size_t size;
    int ret;

    size = sizeof(struct io_uring_cqe); // 16

    // 通过gdb查看
    /**
     * p->sq_off.array = 2368
     * p->sq_entries = 64
     * 
     * p->cq_off.cqes = 320 // 固定320
     * p->cq_entries = 128
     * 
     * 计算出结果
     * sq->ring_sz = 2624
     * cq->ring_sz = 2368
     */
    sq->ring_sz = p->sq_off.array + p->sq_entries * sizeof(unsigned);
    cq->ring_sz = p->cq_off.cqes + p->cq_entries * size;

    // fs/io_uring.c line:10328 会设置IORING_FEAT_SINGLE_MMAP标志
    if (p->features & IORING_FEAT_SINGLE_MMAP) {
        if (cq->ring_sz > sq->ring_sz)
            sq->ring_sz = cq->ring_sz;
        cq->ring_sz = sq->ring_sz;
    }
    /**
     * sq->ring_sz = 2624
     * cq->ring_sz = 2624
     */

    // 创建与内核结构体io_rings的内存映射
    sq->ring_ptr = __sys_mmap(0, sq->ring_sz, PROT_READ | PROT_WRITE,
                  MAP_SHARED | MAP_POPULATE, fd,
                  IORING_OFF_SQ_RING);
    if (IS_ERR(sq->ring_ptr))
        return PTR_ERR(sq->ring_ptr);

    // 共用一份数据
    if (p->features & IORING_FEAT_SINGLE_MMAP) {
        cq->ring_ptr = sq->ring_ptr;
    }

    size = sizeof(struct io_uring_sqe); // 64
    // 创建提交队列的内存映射
    // 此结构体数据用于给用户填充数据, 如通过io_uring_get_sqe获取一个结构体
    // 并通过io_uring_prep_read填充此结构体, 最后通过io_uring_submit提交
    // NOTE 需要注意的是, 通过io_uring_prep_read设置的数据必须保证内存生命周期在完成后
    sq->sqes = __sys_mmap(0, size * p->sq_entries, PROT_READ | PROT_WRITE,
                  MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_SQES);

    // 初始化提交队列和完成队列
    io_uring_setup_ring_pointers(p, sq, cq);
    return 0;
}
解放io_uring编程:liburing实战指南与经典cat示例解析 本文介绍了liburing库的使用方法及其在高性能I/O场景中的优势。文章首先分析了直接使用io_uring原始接口的复杂性,包括手动内存管理和索引计算等问题。通过一个经典的cat程序示例,作者详细讲解了liburing的核心API和工作流程,包括初始化、请求提交、完成事件处理等关键步骤。重点解析了内存对齐(posix_memalign)和柔性数组等关键技术点,并提供了性能对比数据,显示liburing相比传统方式可获得67%的性能提升。文章最后还介绍了批量处理、固定资源注册等高级优化技巧,以及常见的性能问 阅读详情

相关推荐

异步IO -- io_uring

io_uring是一种高效的 Linux 输入/输出(I/O)子系统,用于提高异步I/O的性能和灵活性。它提供了一种比传统的 POSIX 异步 I/O 接口更高效和可扩展的方法来执行文件操作、网络通信等任务。

A152419的博客 1454

io_uring 之 liburing 的简单使用

io_uring是Linux内核在v5.1引入的一套异步IO接口,和aio不同的是,它可以提供更高的性能io_uring 具体有三个系统调用分别是,,,我们可以通过这三个系统调用来完成异步事件提交,收割,自己处理的流程异步io的优点在于,不用我们自己去等待 io操作的完成,我们只需要告诉内核,我们的任务,内核来帮我们完成。这样就可以让我们的进程去干其他的事情,实现更高的吞吐量。io_uring 利用 mmap 开辟出一块空间,让用户态和内核态的程序都可以共享的一块区域。

lins 2660

Linux C系统编程实战指南:从epoll网络编程到内存管理避坑

在Linux系统编程领域,掌握核心系统调用和编程模型是构建高性能、高可靠软件的基础。理解进程间通信、内存管理和网络I/O多路复用等底层原理,是提升代码质量和性能的关键。这些技术广泛应用于服务器开发、嵌入式系统和基础设施软件中,能够有效解决高并发、低延迟等工程挑战。本文聚焦于Linux C编程的实战场景,深入解析epoll事件驱动模型、边缘触发与水平触发的核心差异,并探讨共享内存对齐、缓存伪共享等高级内存管理技巧,旨在帮助开发者规避常见陷阱,编写更健壮的系统级代码。

cunfuxiao7305的博客 771

io_uring、liburing

io_uring是linux内核中高效的异步I/O框架,Linux内核5.1引入,用于提高I/O的性能。liburing是基于io_uring封装的库,提供更简洁的api。

GHL284271090的博客 2256

Linux内核竞争条件漏洞CVE-2026-31431复现与深度分析

竞争条件是并发编程中的经典问题,指多个执行线程以非预期的时序访问共享资源,导致系统状态不一致。其原理在于缺乏足够的同步锁保护,使得“检查”与“使用”操作之间存在脆弱的时间窗口,可被利用破坏安全策略。这类漏洞的技术价值在于揭示了内核安全机制的细微缺陷,常被用于本地权限提升攻击,对操作系统安全构成严重威胁。应用场景广泛,从服务器安全加固到内核开发中的并发安全设计都需重点关注。本文以CVE-2026-31431为例,通过环境搭建、原理剖析和PoC实操,详细展示了如何利用竞争条件漏洞实现提权,并深入探讨了漏洞修复与

weixin_33724659的博客 324

FEMU:基于QEMU的NVMe SSD模拟器编译、配置与三种模式实战

在存储系统与固件开发领域,NVMe SSD的硬件模拟是研究新型文件系统、测试驱动和探索存储架构的关键技术。其核心原理在于通过软件精确模拟SSD的控制器行为、FTL(闪存转换层)逻辑及闪存物理特性,从而在虚拟化环境中构建完整的存储栈闭环。这项技术的价值在于能够低成本、高灵活性地复现各种硬件场景,包括极端故障和尚未面世的设备原型。典型的应用场景包括存储算法研究、系统性能评估以及教育实验。本文聚焦于FEMU这一基于QEMU的高性能NVMe SSD全栈模拟器,详细解析其支持的黑盒SSD、开放通道SSD和NoSSD三

weixin_34323858的博客 415

【io_uring】简介和使用

io_uring 文章目录io_uring简介使用系统调用liburing样例代码流程实现系统调用`io_uring_setup``io_uring_enter``io_uring_register`参考资料 简介 io_uring 是 Linux 在 5.1 版本引入的一套新的异步 IO 实现。相比 Linux 在 2.6 版本引入的 AIO,io_uring 性能强很多,接近 SPDK[1],同时支持 buffer IO io_uring 的作者 Jens Axboe 是 Linux 内核块层和其他块设

乐园 3597

AI开发提效10倍:从需求到部署的全流程实战指南(附Prompt模板)

用AI开发不是“偷懒”,而是把时间花在更有价值的地方——原来花80%时间写重复代码,现在用AI搞定后,能把精力放在“优化用户体验”“提升系统性能”这些核心工作上,这才是AI给开发者的真正红利。如果你还没开始用AI做开发,建议从“写一个简单接口”“补一段注释”开始尝试,先用起来再优化方法。记住:AI是工具,不是对手,学会驾驭它,你会发现开发效率提升的同时,还能告别无效加班。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1530

Linux io_uring机制详解 异步IO原理SQPOLL与性能调优实践

本文深入解析Linux io_uring异步I/O机制,对比传统I/O模型的性能瓶颈,阐述其双环队列(SQ/CQ)架构与共享内存设计如何减少系统调用和内存拷贝开销。重点介绍SQPOLL模式实现零系统调用路径的原理,提供队列深度、资源注册等优化策略,并给出生产环境部署建议。文章包含工程实践模板、常见问题排查清单,强调需结合内核版本、负载特征进行实测验证,避免盲目采用新技术。适用于后端性能优化场景,帮助开发者理解io_uring的高效原理与落地方法。

REDcker的博客 683

Ubuntu 22.04 安装 IsaacLab 2.1.0

本文介绍了IsaacLab的完整安装流程:1)创建Python3.10虚拟环境;2)安装PyTorch2.5.1(CUDA11.8);3)升级pip并安装IsaacSim4.5.0;4)克隆IsaacLab仓库;5)运行安装脚本(需接受EULA)。若遇cmake缺失错误,需执行sudo apt安装。安装完成后可通过Ant-v0训练任务验证,成功运行后将显示IsaacSim窗口和训练完成提示。注意:IsaacSim不同版本可共存于不同环境。

weixin_47880303的博客 2223

STM32-CubeMx-HAL库-串口空闲中断+DMA——利用HAL_UARTEx_ReceiveToIdle_DMA实现不定长数据接收

STM32-CubeMx-HAL库-串口空闲中断+DMA——利用HAL_UARTEx_ReceiveToIdle_DMA实现不定长数据接收

weixin_43864631的博客 1万+

io_uring 用法分析 III :liburing 接口及高性能 Polling 机制

Interrupt 方案是节约 CPU ,但是延迟高,因为用户态正在休眠,调度到他需要花费一定时间(Linux 调度算法是用红黑树的完全公平调度 CFS,和以前看 APUE 的函数调用有关,然后主要优先级依据是通过 virtual runtime 归一化比较的,同等物理时间下高优先级的虚拟时间过得慢,所以能调度多一些)。鉴于 NAPI 已经要求网卡驱动实现本身提供 poll 接口给 trap handler,这样应用层也可以用这个(而 poll 接口也用在 select poll 上

锐龙处理器 5520

电脑的kernelbase.dll故障怎么处理?kernelbase.dll是什么文件

kernelbase.dll​是一个系统文件,属于Microsoft Windows操作系统的一部分。该DLL(动态链接库)文件包含了许多基本且低级的系统函数,这些函数被Windows上运行的各种程序和进程调用。kernelbase.dll通常与Kernel32.dll紧密相关,它是实现许多Windows API(应用程序编程接口)的封装。这些API涉及到内存管理、输入输出操作、进程和线程管理以及其他许多核心的操作系统功能。

电脑修复君的博客 4533

io_uring以及liburing介绍

由于io_uring要实现强大的功能和最优的效率,因此其接口和使用方式会比较复杂。但对于大部分不需要极致IO性能的场景和开发者来说,只使用io_uring的基本功能就能获得大部分的性能收益。当只需要基本功能时,io_uring的复杂接口中很大一部分是不会使用的,同时一部分初始化操作也是基本不变的。因此,io_uring的作者又开发了liburing来简化一般场景下io_uring的使用。

Fiyanna的博客 1131

SAP ERP与金蝶云星空的集成案例(新能源光伏行业)

通过建设PLM、SAP、MES、WMS、SCADA、EAM等多系统集成的工业互联网平台作为数字化工厂的控制中枢,不仅可以实现人员、设备、物料、工艺参数、产品等生产全流程追溯管理,同时也可以根据数据采集进行生产现场的控制调节,最大程度降低能耗水平。销售订单创建下推金蝶采购订单创建修改、销售订单创建下推金蝶销售订单创建修改、销售发货过账下推金蝶采购入库单、销售发货过账下推金蝶销售出库单:在SAP ERP系统创建销售订单、销售发货过账单后推送到云星空系统,进行采购/销售订单的创建修改、完成物料的入库和出库流程。

集信通 1616

27、物联网中的量子密钥分发:安全通信新范式

本文探讨了物联网(IoT)快速发展所带来的安全挑战,并提出量子密钥分发(QKD)作为应对新兴威胁的新范式。文章详细介绍了QKD的基础原理、BB84协议的实现流程以及其在物联网中的应用前景,同时强调了安全专业人员提升技能、制定标准化指南以及跨学科合作的重要性。通过利用量子力学特性,QKD能够提供更高的通信安全性,抵御量子计算等未来威胁,为物联网的安全发展提供保障。

tequila的博客 156

liburing

目录 什么是io_uring? liburing库编译安装 如何使用io_uring/liburing 解放 -------- 这是io_uring库,正在释放。解放提供了帮助者进行设置和 拆卸io_uring实例,以及用于 不需要(或不想)处理完整内核的应用程序 方面的实现。 有关io_uring的更多信息,请参见: https://kernel.dk/io_uring.pdf 订阅io-uring@vger.kernel.org进行io_uring相关讨论 以及内核和用户空间的开发。列表

RToax 3055

华为OD机试 - 机器人活动区域(Python/JS/C/C++ 双机位C卷 200分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。现有一个机器人,可放置于 M × N的网格中任意位置,每个网格包含一个非负整数编号。当相邻网格的数字编号差值的绝对值小于等于 1 时,机器人可在网格间移动问题:求机器人可活动的最大范围对应的网格点数目。说明:1)网格左上角坐标为 (0, 0),右

学Java,找哪吒 1432

文件系统:3. io_uring-io_uring_setup系统调用

文件系统:3. io_uring-io_uring_setup系统调用

苟浩的博客 891

DeerFlow 系列教程 第十六篇 | 实战案例一——用 DeerFlow 进行深度研究

在日常使用 AI Agent 时,最常见的需求之一就是对某个主题进行全面、系统的研究。多源信息采集——不能只依赖单次搜索,需要从多个角度搜索不同来源交叉验证——不同来源的信息需要相互印证,避免单一信源的偏差结构化输出——最终产出的不是零散的信息片段,而是有组织的研究报告传统做法是人工反复搜索、阅读、整理。传统手工研究: DeerFlow 深度研究:人工搜索 → 阅读页面 → 记笔记 提交研究主题│ │▼ ▼换关键词 → 再搜索 → 再阅读 ┌──────────────────┐。

weixin_43674738的博客 162

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

开源项目liburing常见问题解决方案

**项目介绍:** liburing 是一个为 Linux 内核的 io_uring 功能提供帮助函数的库。io_uring 是 Linux 内核提供的一种异步I/O接口,它旨在简化应用程序与内核的I/O交互,提高I/O操作的效率。liburing 提供了设置和拆卸 io_uring 实例的辅助函数,以及一个简化的接口,使得不需要(或不想)处理内核端完整实现的应用程序能够更容易地使用。 **...

gitblog_00630的博客 603

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

从内核看io_uring的实现---第一篇(基于5.9.9)

前言:本文介绍一下Linux下高性能异步IO框架io_uring在内核的实现,因为io_uring实现代码量大,逻辑复杂,所以只能慢慢分析。这一篇介绍io_uring初始化接口io_uring_setup的实现。 io_uring_setup的声明非常简单,但是实现的细节却非常复杂。 static long io_uring_setup(u32 entries, struct io_uring_params __user *params) { struct io_uring_params p; int

标子 的专栏 868

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

liburing终极指南:Linux高性能异步IO完整教程

liburing是Linux系统下实现高性能异步IO的终极解决方案,它为用户空间应用程序提供了简单易用的接口来利用内核的io_uring功能。这个强大的库让开发者能够轻松构建高吞吐量的网络服务器、数据库系统和其他IO密集型应用。🚀 ## 什么是liburing和io_uring? liburing是一个用户空间库,它封装了Linux内核的io_uring接口,使得异步IO编程变得前所未有的简

gitblog_00517的博客 893

【io_uring】内核源码分析

通过提前注册这些缓冲区可以减轻后续每个 IO 的申请资源开销,属于一种高级功能,在这里不做过多展开。主要有三条调用路线(所有调用逻辑都会判断是否在初始化时配置了。的功能比较简单,就是一个代理线程,主要是负责将用户写入。主要用来申请空间,初始化列表头、互斥锁、自旋锁等结构。字段,在指定的 CPU 上启用内核线程。他们的入口都在 Linux 内核源码的。此外在开启了 IOPOLL 模式时,中有过介绍,主要是初始化初始化。时,将启动一个单独的内核线程。函数,否则 IO 将下发失败。的核心系统调用之一,根据。

乐园 5万+

liburing 开源项目安装与使用指南

liburing 开源项目安装与使用指南 项目地址:https://gitcode.com/gh_mirrors/li/liburing 目录结构及介绍 在获取了 liburing 的代码库之后,其主要目录及其功能概述如下: examples: 包含了若干示例程序,如利用 liburing 实现的 cat, cp, 和简单的 Web 服务器等,以展示如何使用本库。 man: 存储着项目的 ...

gitblog_01033的博客 1131

io_uring之liburing库安装

1. 确认库文件的存在:检查 liburing 库文件是否存在于系统中的库路径中。- 如果编译成功,并且没有找到任何与 liburing 相关的链接错误,那么 liburing 库已经成功安装并可以被正确链接。3. 运行示例程序:如果示例程序已经成功编译,您可以尝试运行它,以确保 liburing 在运行时能够正常工作。2. 编译示例程序:尝试编译一个使用 liburing 的示例程序,以验证库是否能够正确链接到应用程序。- 如果找到了 liburing 的库文件路径,说明库已经安装成功。

m0_68678128的博客 4025
上一篇: 纤程与协程以及有栈协程和无栈协程的区别
下一篇: 全局静态变量、全局变量以及atexit回调的执行顺序
山有木兮啊
博客等级 码龄8年 135粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值