昇腾 编程范式 - 矢量编程流水任务设计
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。



![[000-01-008].Seata案例应用](https://i-blog.csdnimg.cn/blog_migrate/fd927ba652f0ca8c66438b2648574b41.png)















