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

Vulkan视频解码decode显示display之同步

在ReleaseDisplayedPicture函数中消耗图片资源并且显示display完成,设置两个标志m_hasConsummerSignalFence = true 和m_hasConsummerSignalSemaphore = true
    virtual int32_t ReleaseDisplayedPicture(DecodedFrameRelease** pDecodedFramesRelease, uint32_t numFramesToRelease)
    {
        std::lock_guard<std::mutex> lock(m_displayQueueMutex);
        for (uint32_t i = 0; i < numFramesToRelease; i++) {
            const DecodedFrameRelease* pDecodedFrameRelease = pDecodedFramesRelease[i];
            int picId = pDecodedFrameRelease->pictureIndex;
            assert((picId >= 0) && ((uint32_t)picId < m_perFrameDecodeImageSet.size()));

            assert(m_perFrameDecodeImageSet[picId].m_decodeOrder == pDecodedFrameRelease->decodeOrder);
            assert(m_perFrameDecodeImageSet[picId].m_displayOrder == pDecodedFrameRelease->displayOrder);

            assert(m_ownedByDisplayMask & (1 << picId));
            m_ownedByDisplayMask &= ~(1 << picId);
            m_perFrameDecodeImageSet[picId].m_inDecodeQueue = false;
            m_perFrameDecodeImageSet[picId].m_ownedByConsummer = false;
            m_perFrameDecodeImageSet[picId].Release();

            m_perFrameDecodeImageSet[picId].m_hasConsummerSignalFence = pDecodedFrameRelease->hasConsummerSignalFence;
            m_perFrameDecodeImageSet[picId].m_hasConsummerSignalSemaphore = pDecodedFrameRelease->hasConsummerSignalSemaphore;

        }
        return 0;
    }

ReleaseDisplayedPicture被ReleaseFrame调用,pLastDecodedFrame就是当前已经解码的帧

.....................................

        m_videoQueue->ReleaseFrame(pLastDecodedFrame);

        pLastDecodedFrame->Reset();

        bool endOfStream = false;
        int32_t numVideoFrames = 0;

        numVideoFrames = m_videoQueue->GetNextFrame(pLastDecodedFrame, &endOfStream);

.............................................

//-----------------------------------------------------------------------

这两个标志一旦设置为true,在QueuePictureForDecode函数中,将设置pFrameSynchronizationInfo->frameConsumerDoneFence和 pFrameSynchronizationInfo->frameConsumerDoneSemaphore,返回后使用,同时重置两个标志为false

    virtual int32_t QueuePictureForDecode(int8_t picId, VkParserDecodePictureInfo* pDecodePictureInfo,
                                          ReferencedObjectsInfo* pReferencedObjectsInfo,
                                          FrameSynchronizationInfo* pFrameSynchronizationInfo)
    {
        if (pFrameSynchronizationInfo->hasFrameCompleteSignalFence) {
            pFrameSynchronizationInfo->frameCompleteFence = m_perFrameDecodeImageSet[picId].m_frameCompleteFence;
            if (pFrameSynchronizationInfo->frameCompleteFence) {
                m_perFrameDecodeImageSet[picId].m_hasFrameCompleteSignalFence = true;
            }
        }

        if (m_perFrameDecodeImageSet[picId].m_hasConsummerSignalFence) {
            pFrameSynchronizationInfo->frameConsumerDoneFence = m_perFrameDecodeImageSet[picId].m_frameConsumerDoneFence;
            m_perFrameDecodeImageSet[picId].m_hasConsummerSignalFence = false;
        }

        if (pFrameSynchronizationInfo->hasFrameCompleteSignalSemaphore) {
            pFrameSynchronizationInfo->frameCompleteSemaphore = m_perFrameDecodeImageSet[picId].m_frameCompleteSemaphore;
            if (pFrameSynchronizationInfo->frameCompleteSemaphore) {
                m_perFrameDecodeImageSet[picId].m_hasFrameCompleteSignalSemaphore = true;
            }
        }

        if (m_perFrameDecodeImageSet[picId].m_hasConsummerSignalSemaphore) {
            pFrameSynchronizationInfo->frameConsumerDoneSemaphore = m_perFrameDecodeImageSet[picId].m_frameConsumerDoneSemaphore;
            m_perFrameDecodeImageSet[picId].m_hasConsummerSignalSemaphore = false;
        }
.................

}

返回后如何使用pFrameSynchronizationInfo->frameConsumerDoneFence和 pFrameSynchronizationInfo->frameConsumerDoneSemaphore,代码如下:

    VkFence frameCompleteFence = frameSynchronizationInfo.frameCompleteFence;
    VkSemaphore frameCompleteSemaphore = frameSynchronizationInfo.frameCompleteSemaphore;
    VkSemaphore frameConsumerDoneSemaphore = frameSynchronizationInfo.frameConsumerDoneSemaphore;

    uint32_t waitSemaphoreCount = 0;
    if (frameConsumerDoneSemaphore != VK_NULL_HANDLE) {
       
waitSemaphores[waitSemaphoreCount] = frameConsumerDoneSemaphore;
        waitSemaphoreCount++;
    }

    VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr };
    const VkPipelineStageFlags videoDecodeSubmitWaitStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
    submitInfo.pNext = (m_hwLoadBalancingTimelineSemaphore != VK_NULL_HANDLE) ? &timelineSemaphoreInfos : nullptr;
    submitInfo.waitSemaphoreCount = waitSemaphoreCount;
    submitInfo.pWaitSemaphores = waitSemaphores;
    submitInfo.pWaitDstStageMask = &videoDecodeSubmitWaitStages;
    submitInfo.commandBufferCount = 1;
    submitInfo.pCommandBuffers = &frameDataSlot.commandBuffer;
    submitInfo.signalSemaphoreCount = signalSemaphoreCount;
    submitInfo.pSignalSemaphores = signalSemaphores;

    assert(VK_NOT_READY == m_vkDevCtx->GetFenceStatus(*m_vkDevCtx, videoDecodeCompleteFence));
    VkResult result = m_vkDevCtx->MultiThreadedQueueSubmit(VulkanDeviceContext::DECODE, m_currentVideoQueueIndx,
                                                           1, &submitInfo, videoDecodeCompleteFence);

拷贝pictureIndex视频帧,并进行等待解码完成并且设置显示完成信号

    virtual int32_t DequeueDecodedPicture(VulkanDecodedFrame* pDecodedFrame)
    {


            if (m_perFrameDecodeImageSet[pictureIndex].m_hasFrameCompleteSignalFence) {
                pDecodedFrame->frameCompleteFence = m_perFrameDecodeImageSet[pictureIndex].m_frameCompleteFence;
                m_perFrameDecodeImageSet[pictureIndex].m_hasFrameCompleteSignalFence = false;
            } else {
                pDecodedFrame->frameCompleteFence = VkFence();
            }

            if (m_perFrameDecodeImageSet[pictureIndex].m_hasFrameCompleteSignalSemaphore) {
                pDecodedFrame->frameCompleteSemaphore = m_perFrameDecodeImageSet[pictureIndex].m_frameCompleteSemaphore;
                m_perFrameDecodeImageSet[pictureIndex].m_hasFrameCompleteSignalSemaphore = false;
            } else {
                pDecodedFrame->frameCompleteSemaphore = VkSemaphore();
            }

            pDecodedFrame->frameConsumerDoneFence = m_perFrameDecodeImageSet[pictureIndex].m_frameConsumerDoneFence;
            pDecodedFrame->frameConsumerDoneSemaphore = m_perFrameDecodeImageSet[pictureIndex].m_frameConsumerDoneSemaphore;

            pDecodedFrame->timestamp = m_perFrameDecodeImageSet[pictureIndex].m_timestamp;
            pDecodedFrame->decodeOrder = m_perFrameDecodeImageSet[pictureIndex].m_decodeOrder;
            pDecodedFrame->displayOrder = m_perFrameDecodeImageSet[pictureIndex].m_displayOrder;

            pDecodedFrame->queryPool = m_queryPool;
            pDecodedFrame->startQueryId = pictureIndex;
            pDecodedFrame->numQueries = 1;

}

//pDecodedFrame传递给DrawFrame最后一个参数pLastDecodedFrame

    VkResult result = DrawFrame(renderIndex,
                                waitSemaphoreCount,
                                pWaitSemaphores,
                                signalSemaphoreCount,
                                pSignalSemaphores,
                                pLastDecodedFrame)

VkResult VulkanFrame<FrameDataType>::DrawFrame( int32_t            renderIndex,
                                                uint32_t           waitSemaphoreCount,
                                                const VkSemaphore* pWaitSemaphores,
                                                uint32_t           signalSemaphoreCount,
                                                const VkSemaphore* pSignalSemaphores,
                                                FrameDataType*     inFrame)

{


    const uint32_t maxWaitSemaphores = 2;
    uint32_t numWaitSemaphores = 0;
    VkSemaphore waitSemaphores[maxWaitSemaphores] = {};

    assert(waitSemaphoreCount <= 1);
    if ((waitSemaphoreCount > 0) && (pWaitSemaphores != nullptr)) {

//这个是等待上一次present完成
        waitSemaphores[numWaitSemaphores++] = *pWaitSemaphores;
    }

    if (inFrame && (inFrame->frameCompleteSemaphore != VkSemaphore())) {

//等待解码完成信号
        waitSemaphores[numWaitSemaphores++] = inFrame->frameCompleteSemaphore;
    }
    assert(numWaitSemaphores <= maxWaitSemaphores);

    const uint32_t maxSignalSemaphores = 2;
    uint32_t numSignalSemaphores = 0;
    VkSemaphore signalSemaphores[maxSignalSemaphores] = {};

    assert(signalSemaphoreCount <= 1);
    if ((signalSemaphoreCount > 0) && (pSignalSemaphores != nullptr)) {
        signalSemaphores[numSignalSemaphores++] = *pSignalSemaphores;
    }

    if (inFrame && (inFrame->frameConsumerDoneSemaphore != VkSemaphore())) {

//显示完成消费信号激活,这样这个图片资源才能被用来继续解码新视频帧,解码函数中需要等待这个frameConsumerDoneSemaphore有信号才能使用这个图片资源解码
        signalSemaphores[numSignalSemaphores++] = inFrame->frameConsumerDoneSemaphore;
        inFrame->hasConsummerSignalSemaphore = true;
    }
    assert(numSignalSemaphores <= maxSignalSemaphores);

    if (frameConsumerDoneFence != VkFence()) {
        inFrame->hasConsummerSignalFence = true;
    }


    // Wait for the image to be owned and signal for render completion
    VkPipelineStageFlags primaryCmdSubmitWaitStages[2] = { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
                                                           VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
    VkSubmitInfo primaryCmdSubmitInfo = VkSubmitInfo();
    primaryCmdSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    primaryCmdSubmitInfo.pWaitDstStageMask = primaryCmdSubmitWaitStages;
    primaryCmdSubmitInfo.commandBufferCount = 1;

    primaryCmdSubmitInfo.waitSemaphoreCount = numWaitSemaphores;
    primaryCmdSubmitInfo.pWaitSemaphores = numWaitSemaphores ? waitSemaphores : NULL;
    primaryCmdSubmitInfo.pCommandBuffers = pPerDrawContext->commandBuffer.GetCommandBuffer();

    primaryCmdSubmitInfo.signalSemaphoreCount = numSignalSemaphores;
    primaryCmdSubmitInfo.pSignalSemaphores = numSignalSemaphores ? signalSemaphores : NULL;

    // For fence/sync debugging
    if (false && inFrame && inFrame->frameCompleteFence) {
        result = m_vkDevCtx->WaitForFences(*m_vkDevCtx, 1, &inFrame->frameCompleteFence, true, 100 * 1000 * 1000);
        assert(result == VK_SUCCESS);
        if (result != VK_SUCCESS) {
            fprintf(stderr, "\nERROR: WaitForFences() result: 0x%x\n", result);
        }
        result = m_vkDevCtx->GetFenceStatus(*m_vkDevCtx, inFrame->frameCompleteFence);
        assert(result == VK_SUCCESS);
        if (result != VK_SUCCESS) {
            fprintf(stderr, "\nERROR: GetFenceStatus() result: 0x%x\n", result);
        }
    }

    result = m_vkDevCtx->MultiThreadedQueueSubmit(VulkanDeviceContext::GRAPHICS, 0, 1, &primaryCmdSubmitInfo, frameConsumerDoneFence);
    if (result != VK_SUCCESS) {
        assert(result == VK_SUCCESS);
        fprintf(stderr, "\nERROR: MultiThreadedQueueSubmit() result: 0x%x\n", result);
        return result;
    }

    if (false && (frameConsumerDoneFence != VkFence())) { // For fence/sync debugging
        const uint64_t fenceTimeout = 100 * 1000 * 1000 /* 100 mSec */;
        result = m_vkDevCtx->WaitForFences(*m_vkDevCtx, 1, &frameConsumerDoneFence, true, fenceTimeout);
        assert(result == VK_SUCCESS);
        if (result != VK_SUCCESS) {
            fprintf(stderr, "\nERROR: WaitForFences() result: 0x%x\n", result);
        }
        result = m_vkDevCtx->GetFenceStatus(*m_vkDevCtx, frameConsumerDoneFence);
        assert(result == VK_SUCCESS);
        if (result != VK_SUCCESS) {
            fprintf(stderr, "\nERROR: GetFenceStatus() result: 0x%x\n", result);
        }
    }

#if 0 // for testing VK_KHR_external_fence_fd
    int fd = -1; // VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
    const VkFenceGetFdInfoKHR getFdInfo =  { VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, NULL, data.lastDecodedFrame.frameConsumerDoneFence, VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT};
    res = m_vkDevCtx->GetFenceFdKHR(*m_vkDevCtx, &getFdInfo, &fd);
    close(fd);
#endif

    m_frameDataIndex = (m_frameDataIndex + 1) % m_frameData.size();

    return result;

}

相关文章:

Vulkan视频解码decode显示display之同步

在ReleaseDisplayedPicture函数中消耗图片资源并且显示display完成&#xff0c;设置两个标志m_hasConsummerSignalFence true 和m_hasConsummerSignalSemaphore true virtual int32_t ReleaseDisplayedPicture(DecodedFrameRelease** pDecodedFramesRelease, uint32_t nu…...

专题|Python梯度提升实例合集:GBM、XGBoost、SMOTE重采样、贝叶斯、逻辑回归、随机森林分析信贷、破产数据...

全文链接&#xff1a;https://tecdat.cn/?p41051 分析师&#xff1a;Jiajie Shi&#xff0c;Yimeng Li 在当今数据驱动的时代&#xff0c;数据分析师和数据建模师面临着各式各样复杂且极具挑战性的任务。本专题合集便是围绕这些挑战展开的宝贵知识盛宴&#xff08;点击文末“阅…...

4.0 相机引导XY轴控制螺丝枪打螺丝

假如一个产品的同一水平上要打6个螺钉&#xff0c;是通过伺服XY轴移动带动相机以及螺丝枪&#xff0c;由相机拍照&#xff0c;根据拍照后螺丝孔位置来引导伺服进行移动以对准螺丝孔位置的。步骤如下&#xff1a; 一、9点标定&#xff0c;即把相机与伺服的实际位置关联起来。步骤…...

【ElasticSearch】学习笔记

一、lucene的组成 segment是一个具备完整搜索功能的最小单元。 多个segment组成了一个单机文本检索库lucene。 inverted index:倒排索引&#xff0c;用于快速根据关键词找到对应的文章term index: 构建出关键词的目录树&#xff0c;解决了term dictionary数据量过大&#xff…...

Spring Boot整合RabbitMQ极简教程

一、消息队列能解决什么问题&#xff1f; 异步处理&#xff1a;解耦耗时操作&#xff08;如发短信、日志记录&#xff09;流量削峰&#xff1a;应对突发请求&#xff0c;避免系统过载应用解耦&#xff1a;服务间通过消息通信&#xff0c;降低依赖 二、快速整合RabbitMQ 1. 环…...

代码随想录-04-字符串-03.替换数字

替换数字 题目 给定一个字符串 s&#xff0c;它包含小写字母和数字字符&#xff0c;请编写一个函数&#xff0c;将字符串中的字母字符保持不变&#xff0c;而将每个数字字符替换为number。 例如&#xff0c;对于输入字符串 “a1b2c3”&#xff0c;函数应该将其转换为 “anum…...

Tailwindcss开启黑夜模式

本篇讲述如何使用tailwindcss切换白天黑夜主题 tailwindcss自带的暗夜切换会比css自带的theme主体切换来得方便很多&#xff0c;学习成本也很低&#xff0c;只要求会用tailiwndcss 1&#xff0c;tailwindcss.config有两种暗夜模式切换&#xff0c;媒体查询和手动类切换。手动控…...

AI与人的智能,改变一生的思维模型【7】易得性偏差

目录 **易得性偏差思维模型&#xff1a;大脑的「热搜算法」与反操纵指南****病毒式定义&#xff1a;你的大脑正在被「热搜」劫持****四大核心攻击路径与史诗级案例****1. 信息过载时代的「认知短路」****2. 媒体放大器的「恐怖滤镜」****3. 个人经验的「数据暴政」****4. 社交茧…...

有序表--跳表

实现一种结构&#xff0c;支持如下操作&#xff0c;要求单次调用的时间复杂度O(log n) 1&#xff0c;增加x&#xff0c;重复加入算多个词频 2&#xff0c;删除x&#xff0c;如果有多个&#xff0c;只删掉一个 3&#xff0c;查询x的排名&#xff0c;x的排名为&#xff0c;比x小的…...

双指针---字符串替换数字(数字替换为“number“)

题目链接&#xff1a;替换数字 要求&#xff1a;时间复杂度为O(n) 思路&#xff1a; 1、先将字符串扩容到要输出串的长度。 2、从后向前替换数字字符&#xff0c;也就是双指针法&#xff0c;newIndex指向新长度的末尾&#xff0c;i指向旧长度的末尾。 #include<iostream&g…...

外星人入侵-Python-三

武装飞船 开发一个名为《外星人入侵》的游戏吧&#xff01;为此将使用 Pygame&#xff0c;这是一组功能强大而有趣的模块&#xff0c;可用于管理图形、动画乃至声音&#xff0c; 让你能够更轻松地开发复杂的游戏。通过使用Pygame来处理在屏幕上绘制图像 等任务&#xff0c;可将…...

JavaScript相关面试题

以下是150道JavaScript相关面试题及详细答案&#xff1a; JavaScript基础 1.JavaScript是什么&#xff1f; JavaScript是一种直译式脚本语言&#xff0c;主要用于网页开发&#xff0c;也可用于服务器端开发&#xff08;如Node.js&#xff09;。它是一种动态类型、弱类型、基于原…...

常见的数学模型

数学模型的基本原理 简单来说&#xff0c;数学模型就是用数学语言来描述现实世界中的现象或规律。它就像一个“翻译器”&#xff0c;把复杂的现实问题转化成我们可以用数学方法解决的问题。 核心思想&#xff1a; 简化现实&#xff1a;现实世界太复杂&#xff0c;模型会抓住最…...

计算机四级 - 数据库原理 - 第3章 「关系数据库系统概述」

3.1 关系数据库系统概述 关系数据模型的三大要素&#xff1a;关系数据结构、关系操作集合&#xff08;一次一个集合&#xff09;和关系完整性约束 1. 关系语言的特点是高度非过程化的, DBMS会自动帮用户选择存取路径&#xff0c;用户不需要依靠循环和递归完成数据的重复操作。…...

使用PHP进行自动化测试:工具与策略的全面分析

使用PHP进行自动化测试&#xff1a;工具与策略的全面分析 引言 随着软件开发的复杂性不断增加&#xff0c;自动化测试已成为确保软件质量的关键环节。PHP作为一种广泛使用的服务器端脚本语言&#xff0c;拥有丰富的生态系统和工具支持&#xff0c;使其成为自动化测试的理想选…...

discuz门户文章允许游客评论

discuz开启游客评论 1、进入后台&#xff0c;用户--用户组--系统用户组--游客--编辑 2、论坛相关 设置未允许发表回复 3、门户相关--文章评论字数(设置此用户组发表文章评论字数限制&#xff0c;设置为0将禁止此用户组发表评论) 4、验证游客回复 测试站 http://jinzhu.zhaowo.…...

AtCoder Beginner Contest 003(A - 社の給料、B -トランプ、C -プログラミング講座、D - 社の冬 )题目讲解

前言 又更新AtCoder Beginner Contes 的题目讲解啦!! 希望能给诸位带来帮助。 话不多说,开始讲解: A - 社の給料←题目翻译 为了解决这个问题,我们需要计算青木每月完成正好N个任务时的平均工资。通过分析,我们可以发现这个问题可以通过数学公式直接求解,而不需要复…...

代码随想录二刷|图论11

图论 一、基础知识 1 无向图 &#xff08;1&#xff09;度&#xff1a;一个顶点连n条边就度为n &#xff08;2&#xff09;权 加权无向图&#xff1a;有边长的无向图 &#xff08;3&#xff09;通道&#xff1a;两个顶点之间有一些边和点&#xff0c;并且没有重复的边 路…...

农资出入库登记本,农药化肥库存出入库软件,佳易王农资管理庄稼医院开单管理系统操作教程

一、概述 本实例以佳易王农资管理庄稼医院开单管理系统为例说明&#xff0c;其他版本可参考本实例。试用版软件资源可到文章最后了解&#xff0c;下载的文件为压缩包文件&#xff0c;请使用免费版的解压工具解压即可试用。 软件特点&#xff1a; 1、功能实用&#xff0c;操作简…...

串的KMP算法详解

KMP算法深度解析 一、从暴力匹配到智能跳转&#xff1a; 在文本编辑器的搜索功能中&#xff0c;当我们在百万字的文档中查找特定关键词时&#xff0c;传统暴力匹配算法的时间复杂度高达O(mn)。KMP算法通过独创的部分匹配表&#xff08;Partial Match Table&#xff09;&#x…...

软件测试之测试分类

1. 为什么要对软件测试进行分类 软件测试是软件⽣命周期中的⼀个重要环节&#xff0c;具有较⾼的复杂性&#xff0c;对于软件测试&#xff0c;可以从不同的⻆度 加以分类&#xff0c;使开发者在软件开发过程中的不同层次、不同阶段对测试⼯作进⾏更好的执⾏和管理测试 的分类⽅…...

机器学习 : 训练过程

文章目录 概要流程1 . 前向传播2 . 计算损失3 . 后向传播4 . 梯度下降 技术名词解释小结 【全文大纲】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 概要 主要思想拟合数据 流程 1 . 前向传播 y func * (wxb) 2 . 计算损失 y - Y 3 . 后向传播 根据链式法…...

六十天前端强化训练之第二十天React Router 基础详解

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、核心概念 1.1 核心组件 1.2 路由模式对比 二、核心代码示例 2.1 基础路由配置 2.2 动态路由示例 2.3 嵌套路由实现 2.4 完整示例代码 三、关键功能实现效果 四、…...

如何在AVL树中高效插入并保持平衡:一步步掌握旋转与平衡因子 —— 旋转篇

文章目录 AVL树种旋转的规则右单旋右单旋代码左单旋左单旋代码左右双旋左右单旋的代码右左单旋右左单旋的代码 AVL树种旋转的规则 在AVL树中&#xff0c;旋转是为了保持树的平衡性。AVL树是一种自平衡的二叉搜索树&#xff0c;它要求每个节点的左右子树的高度差不能超过1。当插…...

C++Primer学习(7.1 定义抽象数据类型)

类的基本思想是数据抽象(data abstraction)和封装(encapsulation)。数据抽象是种依赖于接口(interface)和实现(implementation)分离的编程(以及设计)技术。类的接口包括用户所能执行的操作:类的实现则包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。 封…...

Vue 3 Diff 算法深度解析:与 Vue 2 双端比对对比

文章目录 1. 核心算法概述1.1 Vue 2 双端比对算法1.2 Vue 3 快速 Diff 算法 2. 算法复杂度分析2.1 时间复杂度对比2.2 空间复杂度对比 3. 核心实现解析3.1 Vue 2 双端比对代码3.2 Vue 3 快速 Diff 代码 4. 性能优化分析4.1 性能测试数据4.2 内存使用对比 5. 使用场景分析5.1 Vu…...

启动桌面Docker提示虚拟服务未启动

在启动 Docker Desktop 时&#xff0c;可能会遇到以下提示&#xff1a; Docker Desktop - Virtual Machine Platform not enabled Virtual Machine Platform not enabled该错误通常是由于 Windows 未启用 “Virtual Machine Platform” 功能导致的&#xff0c;这是运行 Docker…...

【SpringBoot】实现登录功能

在上一篇博客中&#xff0c;我们讲解了注册页面的实现。在此基础上会跳转到登录页面&#xff0c;今天给大家带来的是使用 SpringBoot&#xff0c;MyBatis&#xff0c;Html&#xff0c;CSS&#xff0c;JavaScript&#xff0c;前后端交互实现一个登录功能。 目录 一、效果 二、…...

DataWhale 速通AI编程开发:(进阶篇)第3章 提示词(Prompts)配置项

学习网址&#xff1a;Datawhale-学用 AI,从此开始 3.1 Roo Code提示词配置了什么 众所周知&#xff0c;提示词&#xff08;Prompt&#xff09;是用户向大语言模型输入的一段文本&#xff0c;用于指导大语言模型生成符合用户要求的输出。在ai编程领域更是如此&#xff0c;提示…...

VUE中VNode(虚拟节点)是个啥?

用 JavaScript 生成 Virtual DOM&#xff08;VNode&#xff09; 在 Vue 中&#xff0c;Virtual DOM&#xff08;虚拟 DOM&#xff09;是一个用 JavaScript 对象表示真实 DOM 结构的抽象层。通过这种方式&#xff0c;Vue 可以通过比较 Virtual DOM 与真实 DOM 的差异来最小化更…...

力扣:3. 无重复字符的最长子串(滑动窗口)

3. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09;3. 无重复字符的最长子串 - 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1:输入: s "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc"…...

注解+AOP实现权限控制

注解与AOP实战&#xff1a;实现权限控制 在现代Java开发中&#xff0c;注解&#xff08;Annotation&#xff09;和面向切面编程&#xff08;AOP&#xff09;是两种强大的技术&#xff0c;它们能够帮助我们实现代码的解耦&#xff0c;提高代码的可读性和可维护性。本文将通过一…...

2.5 python接口编程

在现代软件开发的复杂生态系统中&#xff0c;不同系统、模块之间的交互协作至关重要。接口编程作为一种关键机制&#xff0c;定义了组件之间的通信规范与交互方式。Python 凭借其卓越的灵活性、丰富的库资源以及简洁易读的语法&#xff0c;在接口编程领域占据了重要地位&#x…...

睡不着运动锻炼贴士

在快节奏的现代生活中&#xff0c;失眠似乎已成为许多人的“夜间伴侣”。夜晚辗转反侧&#xff0c;白天精神不振&#xff0c;这样的恶性循环让许多人苦不堪言。其实&#xff0c;除了调整作息和饮食习惯&#xff0c;适当的运动也是改善睡眠的一剂良药。今天&#xff0c;就让我们…...

【Python入门】一篇掌握Python中的字典(创建、访问、修改、字典方法)【详细版】

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;《Python/PyTorch极简课》_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目…...

深入理解 HTML 表单与输入

在网页开发的广袤领域中&#xff0c;HTML 表单如同搭建用户与服务器沟通桥梁的基石。它是收集用户输入信息的关键渠道&#xff0c;承载着交互的重任。今天&#xff0c;就让我们一同深入探索 HTML 表单与输入的奥秘。​ HTML 表单在文档中划定出一片独特的区域&#xff0c;这片…...

宝塔docker切换存储目录

1、 停止 Docker 服务 sudo systemctl stop docker2、迁移 Docker 数据目录 sudo mkdir -p /newpath/docker sudo rsync -avz /var/lib/docker/ /newpath/docker/3、修改 Docker 配置文件 vi /etc/docker/daemon.json 内容 {"data-root": "/newpath/docker&q…...

IPoIB驱动中RSS与TSS技术的深度解析:多队列机制与性能优化

在高速网络通信中,IP over InfiniBand(IPoIB) 是实现低延迟、高吞吐的关键技术之一。为了充分发挥多核处理器的性能潜力,IPoIB驱动通过 接收侧扩展(RSS) 和 发送侧扩展(TSS) 技术,实现了数据包处理的多队列并行化。本文结合源码实现与性能优化策略,深入解析其核心机制…...

目前人工智能的发展,判断10年、20年后的人工智能发展的主要方向,或者带动的主要产业

根据2025年的最新行业研究和技术演进趋势&#xff0c;结合历史发展轨迹&#xff0c;未来10-20年人工智能发展的主要方向及带动的产业将呈现以下六大核心趋势&#xff1a; 一、算力革命与底层架构优化 核心地位&#xff1a;算力将成为类似“新能源电池”的基础设施&#xff0c;…...

DeepSeek-prompt指令-当DeepSeek答非所问,应该如何准确的表达我们的诉求?

当DeepSeek答非所问&#xff0c;应该如何准确的表达我们的诉求&#xff1f;不同使用场景如何向DeepSeek发问&#xff1f;是否有指令公式&#xff1f; 目录 1、 扮演专家型指令2、 知识蒸馏型指令3、 颗粒度调节型指令4、 时间轴推演型指令5、 极端测试型6、 逆向思维型指令7、…...

并发编程面试题二

1、java线程常见的基本状态有哪些&#xff0c;这些状态分别是做什么的 &#xff08;1&#xff09;创建&#xff08;New&#xff09;&#xff1a;new Thread()&#xff0c;生成线程对象。 &#xff08;2&#xff09;就绪&#xff08;Runnable&#xff09;:当调用线程对象的sta…...

【NLP】 8. 处理常见词(Stopwords)的不同策略

处理常见词&#xff08;Stopwords&#xff09;的不同策略 在自然语言处理 (NLP) 和信息检索 (IR) 任务中&#xff0c;常见词&#xff08;Stopwords&#xff09; 是指在文本中频繁出现但通常对主要任务贡献较小的词&#xff0c;例如 “the”、“is”、“in”、“and” 等。这些…...

【Java基础】java中的lambda表达式

Java Lambda表达式深度解析&#xff1a;语法、简化规则与实战 前言 Java 8的Lambda表达式通过简化匿名内部类和引入函数式编程&#xff0c;极大提升了代码的简洁性和可读性。 一、Lambda表达式的核心语法 Lambda表达式由参数列表、->符号和表达式主体组成&#xff0c;其基…...

【RS】OneRec快手-生成式推荐模型

note 本文提出了一种名为 OneRec 的统一生成式推荐框架&#xff0c;旨在替代传统的多阶段排序策略&#xff0c;通过一个端到端的生成模型直接生成推荐结果。OneRec 的主要贡献包括&#xff1a; 编码器-解码器结构&#xff1a;采用稀疏混合专家&#xff08;MoE&#xff09;架构…...

DQN 玩 2048 实战|第一期!搭建游戏环境(附 PyGame 可视化源码)

视频讲解&#xff1a; DQN 玩 2048 实战&#xff5c;第一期&#xff01;搭建游戏环境&#xff08;附 PyGame 可视化源码&#xff09; 代码仓库&#xff1a;GitHub - LitchiCheng/DRL-learning: 深度强化学习 2048游戏介绍&#xff0c;引用维基百科 《2048》在44的网格上进行。…...

练习题:87

目录 Python题目 题目 题目分析 代码实现 代码解释 列表推导式部分&#xff1a; 变量赋值和输出&#xff1a; 运行思路 结束语 Python题目 题目 使用列表推导式生成一个包含 1 到 100 中所有偶数的列表。 题目分析 本题要求使用 Python 的列表推导式生成一个包含 …...

二叉树的层序遍历(102)

102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* …...

NVMe集群:加速数据处理

随着大数据和云计算的快速发展&#xff0c;企业面临着前所未有的数据处理挑战。传统的存储技术和架构已经难以满足现代应用对高性能和低延迟的需求。在这种背景下&#xff0c;NVMe&#xff08;Non-Volatile Memory Express&#xff09;集群应运而生&#xff0c;它以其卓越的性能…...

JUC并发编程:共享模型之管程

一、共享带来的问题 &#xff08;1&#xff09;Java的体现 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&#xff0c;各做 5000 次&#xff0c;结果是 0 吗&#xff1f; &#xff08;2&#xff09;问题分析 以上的结果可能是正数、负数、零。为什么呢…...

Java构造方法详解:从入门到实战

目录 一、什么是构造方法&#xff1f; 二、构造方法的作用 三、构造方法分类与使用 1. 默认构造方法 2. 有参构造方法 3. 构造方法重载 四、注意事项&#xff08;避坑指南&#xff09; 五、经典面试题解析 六、实战应用场景 七、总结 一、什么是构造方法&#xff1f; …...