昇腾 编程范式 - 矢量编程流水任务设计

news2024/9/21 18:39:04

昇腾 编程范式 - 矢量编程流水任务设计

flyfish

编程范式简单来说就是不同编程风格或方式的“套路”。按着套路走就可以。

矢量算子编程范式把算子的实现流程分为3个基本任务:CopyOut,Compute,copyout
CopyIn负责数据搬入操作,
Compute负责矢量计算操作,
CopyOut负责数据搬出操作请添加图片描述
在这里插入图片描述
代码解释使用C++标准库实现,容易编译
TQue<QuePosition::VECOUT, 10> outQueueZ形式的解释
QuePosition 枚举:
定义了 VECIN 和 VECOUT,用来区分输入队列和输出队列。

TQue 模板类:
TQue 类模板接收两个模板参数:一个是 QuePosition 枚举值,用来表示队列的位置;另一个是 BufferSize,表示队列的缓冲区大小。
TQue 类内部定义了一个 std::vector 作为缓冲区,enqueue 方法用于添加数据,dequeue 方法用于取出数据

仅用于语法解释,非线程安全

#include <iostream>
#include <vector>

// 定义枚举类型,表示队列位置或类型
enum class QuePosition {
    VECIN,  // 输入队列
    VECOUT  // 输出队列
};

// 定义模板类 TQue,模板参数为队列位置和缓冲区大小
template <QuePosition Position, size_t BufferSize>
class TQue {
public:
    TQue() {
        buffer.resize(BufferSize);
    }

    // 模拟添加数据到队列中
    void enqueue(const int& data) {
        if (size < BufferSize) {
            buffer[size++] = data;
        } else {
            std::cerr << "Queue is full!" << std::endl;
        }
    }

    // 模拟从队列中取出数据
    int dequeue() {
        if (size > 0) {
            return buffer[--size];
        } else {
            std::cerr << "Queue is empty!" << std::endl;
            return -1; // 返回-1表示队列为空
        }
    }

private:
    std::vector<int> buffer; // 队列缓冲区
    size_t size = 0;         // 当前队列中的元素数量
};

int main() {
    // 实例化输入和输出队列对象
    TQue<QuePosition::VECIN, 10> inQueueX, inQueueY; // 输入队列
    TQue<QuePosition::VECOUT, 10> outQueueZ;         // 输出队列

    // 向输入队列添加数据
    inQueueX.enqueue(1);
    inQueueY.enqueue(2);

    // 从输出队列取出数据
    int dataX = inQueueX.dequeue();
    int dataY = inQueueY.dequeue();

    // 输出结果
    std::cout << "Dequeued from inQueueX: " << dataX << std::endl;
    std::cout << "Dequeued from inQueueY: " << dataY << std::endl;

    return 0;
}

使用 Double Buffer 技术优化计算

代码仅用于解释,使用两个缓冲区来实现这一技术,使得在一个缓冲区进行计算的同时,另一个缓冲区可以进行数据搬运操作。


#include <iostream>
#include <thread>
#include <vector>

// 模拟数据搬运(从内存拷贝数据到缓冲区)
void copyIn(int* buffer, int size) {
    for (int i = 0; i < size; ++i) {
        buffer[i] = i;
    }
    std::cout << "Copy In Complete" << std::endl;
}

// 模拟数据搬运(从缓冲区拷贝数据到内存)
void copyOut(int* buffer, int size) {
    // 模拟将数据输出到某个位置
    for (int i = 0; i < size; ++i) {
        // 这里仅作示范,不实际搬运数据
    }
    std::cout << "Copy Out Complete" << std::endl;
}

// 模拟矢量计算
void compute(int* buffer, int size) {
    for (int i = 0; i < size; ++i) {
        buffer[i] *= 2; // 简单的计算,将每个元素乘以2
    }
    std::cout << "Compute Complete" << std::endl;
}

int main() {
    const int bufferSize = 100;
    int tensor1[bufferSize];
    int tensor2[bufferSize];

    // 启动双缓冲优化
    std::thread copyInThread(copyIn, tensor1, bufferSize);  // 对 tensor1 进行数据搬运
    copyInThread.join();

    std::thread computeThread1(compute, tensor1, bufferSize);  // 对 tensor1 进行计算
    std::thread copyInThread2(copyIn, tensor2, bufferSize);    // 同时对 tensor2 进行数据搬运

    computeThread1.join();
    copyInThread2.join();

    std::thread computeThread2(compute, tensor2, bufferSize);  // 对 tensor2 进行计算
    std::thread copyOutThread(copyOut, tensor1, bufferSize);   // 同时对 tensor1 进行数据搬出

    computeThread2.join();
    copyOutThread.join();

    std::thread copyOutThread2(copyOut, tensor2, bufferSize);  // 最后对 tensor2 进行数据搬出
    copyOutThread2.join();

    std::cout << "Double Buffering Complete" << std::endl;

    return 0;
}

输出

Copy In Complete
Copy In Complete
Compute Complete
Compute Complete
Copy Out Complete
Copy Out Complete
Double Buffering Complete

上面写的代码模拟copyIn、copyOut、compute 函数:
copyIn 函数模拟从内存将数据搬运到缓冲区中。
copyOut 函数模拟从缓冲区将数据搬运到内存中。
compute 函数对缓冲区中的数据进行计算。在这个例子中,计算内容很简单:将每个元素乘以2。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2096471.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring入门(一)spring简介

一、spring简介 Spring技术是JavaEE开发必备技能&#xff0c;企业开发技术选型命中率>90% spring能够简化开发&#xff0c;降低企业级开发的复杂性。框架整合&#xff0c;高效整合其他技术&#xff0c;提高企业级应用开发与运行效率。 主要学习&…

Leetcode3244. 新增道路查询后的最短距离 II

Every day a Leetcode 题目来源&#xff1a;3244. 新增道路查询后的最短距离 II 解法1&#xff1a;贪心 由于题目保证添加的边&#xff08;捷径&#xff09;不会交叉&#xff0c;从贪心的角度看&#xff0c;遇到捷径就走捷径是最优的。所有被跳过的城市都不可能再出现在最短…

从人机环境系统的角度看,自下而上和自上而下两种认知方式如何有机地结合使用?...

从具体的“态”到抽象的“势”&#xff0c;从感觉到认知是自下而上的&#xff0c;例如 GPT&#xff1b;反之&#xff0c;则是自上而下的&#xff0c;比如有经验的人。理性偏自下而上&#xff0c;神性&#xff08;感觉&#xff09;则自上而下。其中&#xff0c;“态”和“势”是…

[000-01-008].Seata案例应用

业务说明&#xff1a;这里我们创建三个服务&#xff0c;一个订单服务&#xff0c;一个库存服务&#xff0c;一个账户服务。当用户下单时&#xff0c;会在订单服务中创建一个订单&#xff0c;然后通过远程调用库存服务来扣减下单商品的库存&#xff1b;再通过远程调用账户服务来…

如何用命令行工作流做定制化 AI 文献回顾?

&#xff08;注&#xff1a;本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费&#xff09; 千万不要把 AI 生成的结果&#xff0c;直接端出去给你的导师&#xff0c;甚至是投稿到出版社。 需求 我最近在 B 站发布了一个视频&#xff0c;叫做《AI…

Redis:Redis性能影响因素

这里写自定义目录标题 一、CPU对Redis的影响二、磁盘对Redis的影响三、网络对Redis的影响四、Swap对Redis的影响 一、CPU对Redis的影响 二、磁盘对Redis的影响 性能建议&#xff1a; 如果是热点场景&#xff0c;建议大家关闭rdb和aof。在SATA和SAS普通盘上&#xff0c;append…

【微服务】springboot 自定义注解+反射+aop实现动态修改请求参数

目录 一、前言 二、动态修改接口请求参数的场景 2.1 动态修改请求参场景汇总 2.1.1 数据格式标准化 2.1.2 安全需要 2.1.3 参数校验与默认值设定 2.1.4 数据隐私保护 2.1.5 适配不同客户端 2.1.6 统计与监控 2.1.7 高级功能特性 三、springboot 使用过滤器和拦截器动…

Mysql8 主从复制主从切换(超详细)

文章目录 1 主从复制1.1 实施前提1.2 主节点配置(在192.168.25.91操作)1.3 从节点配置(在192.168.25.92操作)1.4 创建用于主从同步的用户1.5 开启主从同步1.5 主从同步验证 2 主从切换2.1 实施前提2.2 主节点设置只读(在192.168.25.91操作)2.3 检查主从数据是否同步完毕(在192.…

Vue的冷门内置指令:优化与性能提升的利器

在Vue.js的广阔生态中&#xff0c;开发者们常常聚焦于那些耳熟能详的内置指令&#xff0c;如v-for用于循环渲染列表&#xff0c;v-if和v-else-if用于条件渲染等。然而&#xff0c;Vue还提供了一系列较为冷门但功能强大的内置指令&#xff0c;它们在某些特定场景下能够显著提升应…

ER模型介绍

7.1.概述&#xff1a; 1.ER模型也叫做实体关系模型&#xff0c;是用来描述现实生活中客观存在的事物、事物的属性&#xff0c;以及事物之间关系的一种数据模型。2.在开发基于数据库的信息系统的设计阶段&#xff0c;通常使用ER模型来描述信息需要和信息特性&#xff0c;帮助我…

云平台之Zabbix 监控网站

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

NMPC非线性模型预测控制经验分享与代码实例

NMPC非线性模型预测控制经验分享与代码实例 原本做完本科毕设之后就应该动笔写这一部分&#xff0c;但是做的过程中慢慢意识到自己懂的只是一点点。最近重新接触一些优化相关的问题&#xff0c;希望能够做出我认知之下比较好的解答。本人知识有限&#xff0c;难免写的有问题&am…

ClickHousez中如何定时清理过期数据库?

一、脚本清理 要在ClickHouse中自动删除过期的数据库&#xff0c;你可以使用ClickHouse的SQL命令结合外部脚本&#xff08;如Shell脚本&#xff09;和计划任务&#xff08;如cron&#xff09;来实现。下面是一个示例&#xff0c;展示如何创建一个Shell脚本来检查数据库的创建时…

1、.Net UI框架:Avalonia UI - .Net宣传系列文章

Avalonia UI是一个开源的跨平台UI框架&#xff0c;它允许开发者使用C#和XAML来创建应用程序&#xff0c;这些应用程序可以在多个平台上运行&#xff0c;包括Windows、macOS、Linux、Android和iOS。Avalonia UI的设计目标是提供一个现代化、可移植的UI框架&#xff0c;它具有类似…

C++之搜索二叉树(上)

目录 搜索二叉树的概念 搜索二叉树的操作 递归版本 二叉树的插入 二叉树的查找 二叉树的删除 非递归版本 二叉树的递归插入 二叉树的递归查找 二叉树的递归删除 在之前我们已经学习过了二叉树这一数据结构&#xff0c;本期我们将学习一种新的数据结构------搜索二…

Ubuntu服务器时间和本地时间不一致怎么解决——Linux的Local Time和RTC time

最近一直在搞大模型的相关工作&#xff0c;所以一直在用Linux服务器&#xff0c;前面的文章里也提到了&#xff0c;我用的是一台Dell PowerEdge R730xd。 但在使用中发现&#xff0c;IDRAC中的日志时间和本地时间存在时差&#xff0c;大概相关8小时。 对于技术人员&#xff0c…

UE5学习笔记19-服务器的更新频率,根骨骼旋转节点

一、服务器向客户端发送数据的频率 在Config中的DefaultEngine.ini文件添加 [/Script/OnlineSubsystemUtils.IpNetDriver] NetServerMaxTickRate60; 二、角色类中&#xff0c;角色蓝图类中在细节面板收缩net可以在界面中找到下面两个变量 NetUpdateFrequency 66.f; //净更…

代码随想录Day 32|leetcode题目:501.斐波那契数、70.爬楼梯、746.使用最小花费爬楼梯

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 动态规划理论基础一、理论基础1.1 什么是动态规划1.2 动态规划的解题步骤1.3 动态规划应该如何debug 二、题目题目一&#xff1a; 509. 斐波那契数解题思路&#xff1a;动态规划递归解法 题目二&a…

spring boot 项目 prometheus 自定义指标收集区分应用环境集群实例ip,使用 grafana 查询--方法耗时分位数指标

spring boot 项目 prometheus 自定义指标收集 auth author JellyfishMIX - github / blog.jellyfishmix.comLICENSE LICENSE-2.0 说明 网上有很多 promehteus 和 grafana 配置&#xff0c;本文不再重复&#xff0c;只介绍自定义部分。目前只介绍了分位数指标的收集和查询&a…

基于nodejs+vue+uniapp的摄影竞赛小程序

开发语言&#xff1a;Nodejs框架&#xff1a;expressuniapp数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;VS Code 系统展示 管理员登录 管理员主界面 用户管理 书籍分类管理 书籍信息管理 系统管理…