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

【C++游戏引擎开发】《线性代数》(2):矩阵加减法与SIMD集成

一、矩阵加减法数学原理

1.1 定义

  • ​逐元素操作:运算仅针对相同位置的元素,不涉及矩阵乘法或行列变换。
  • ​交换律与结合律:
    加法满足交换律(A + B = B + A)和结合律( ( A + B ) + C = A + ( B + C ) )。
    ​减法不满足交换律(A − B ≠ B − A)。

1.2 公式

C i j = A i j + B i j (矩阵加法) C_{ij} = A_{ij} + B_{ij} \quad \text{(矩阵加法)} Cij=Aij+Bij(矩阵加法)
C i j = A i j − B i j (矩阵减法) C_{ij} = A_{ij} - B_{ij} \quad \text{(矩阵减法)} Cij=AijBij(矩阵减法)

前提条件:两个矩阵的行列数必须相同。


二、SIMD指令集简介

2.1 AVX2基础

  • 256位寄存器(__m256),单寄存器可存储8个float
  • 关键指令:
_mm256_load_ps()    // 从对齐内存加载数据到寄存器  
_mm256_add_ps()     // 寄存器加法
_mm256_sub_ps()     // 寄存器减法  
_mm256_store_ps()   // 将寄存器数据存回内存  

2.2 头文件

#include <immintrin.h>  // AVX指令集头文件  

三、SIMD优化矩阵加法实现

3.1 内存管理与对齐

Matrix(size_t rows, size_t cols)
    : rows_(rows), cols_(cols),
      data_(static_cast<float*>(_aligned_malloc(rows* cols * sizeof(float), kSimdAlignment))) {
   
    if (!data_) throw std::bad_alloc();
    // 显式初始化内存为0
    std::memset(data_, 0, rows * cols * sizeof(float));
}

~Matrix() {
    _aligned_free(data_); }
  • 功能:确保矩阵数据内存按32字节对齐(AVX2指令集要求)
  • 关键点
    a) 使用 _aligned_malloc 分配对齐内存
    b) 析构时通过 _aligned_free 释放内存
    c) 内存不足时抛出 bad_alloc 异常

3.2 二维下标访问

class RowProxy {
   
public:
    float& operator[](size_t col) {
   
        if (col >= cols_) throw std::out_of_range("Column index out of range");
        return row_start_[col];
    }
    // ...
};

RowProxy operator[](size_t row) {
   
    if (row >= rows_) throw std::out_of_range("Row index out of range");
    return RowProxy(data_ + row * cols_, cols_);
}
  • 设计目标:实现类似原生二维数组的 matrix[i][j] 语法
  • 实现原理
    a) operator[] 返回临时代理对象 RowProxy
    b) 代理对象二次重载 operator[] 实现列访问
    c) 每次访问自动验证行列索引合法性
  • 优势
    a) 语法直观:mat[1][2] = 3.0f;
    b) 安全性:自动边界检查
    c) 性能:代理对象轻量(仅存储指针和列数)

3.3 SIMD优化加减法

Matrix add_simd(const Matrix& other) const {
   
    validate_dimension(other); // 维度校验
    Matrix result(rows_, cols_);
    
    // AVX指令处理主体数据(每次8个float)
    

http://www.kler.cn/a/612519.html

相关文章:

  • PHP 应用SQL 注入符号拼接请求方法HTTP 头JSON编码类
  • 鸿蒙 ArkUI 进行网络状态监听封装
  • vector和list区别
  • leetcode240.搜索二维矩阵||
  • Flask接口开发--引入mysql
  • Qt:QWebEngineView显示网页失败
  • Android 底部EditView输入时悬浮到软键盘上方
  • 无人机产教融合新方向,装调检修技术详解
  • 前缀和、差分
  • C语言--文件操作教案
  • Mybatis缓存模块分析-源码
  • C# SerialPort 类中清空缓存区的方法
  • 如何使用腾讯云HAI快速、高质量生成Stable Diffusion图片
  • vmwaretools解压失败|vmware tools distrib cannot mkdir read only file system|bug汇总
  • 2025年渗透测试面试题总结-某奇安信-Ateam(题目+回答)
  • Oracle初识:登录方法、导入dmp文件
  • Qt弹出新窗口并关闭(一个按钮)
  • JVM 概述/结构/架构/生命周期
  • 短信验证码安全需求设计
  • C语言 【实现电脑关机小游戏】非常好玩