【WebGPU學習雜記】WebAssembly中的relaxed_madd指令到底做了什么?

relaxed_madd 這條指令到底做了什么


核心:relaxed_madd 是一個分量級別 (Component-wise) 的操作

首先,最重要的一點是:v128.relaxed_madd<f32>(a, b, c) 不是矩陣乘法。它是一個在三個向量 a, b, c 之間進行的、逐個分量的、并行的融合乘加操作。

這三個向量 a, b, c 都是 v128 類型,我們可以把它們看作包含四個 32位浮點數 (f32) 的數組。

1. 定義我們的輸入向量

讓我們用數學形式來表示這三個輸入向量 a, b, c

  • 向量 a?=(a0a1a2a3)\vec{a} = \begin{pmatrix} a_0 \\ a_1 \\ a_2 \\ a_3 \end{pmatrix}a=?a0?a1?a2?a3???
  • 向量 b?=(b0b1b2b3)\vec{b} = \begin{pmatrix} b_0 \\ b_1 \\ b_2 \\ b_3 \end{pmatrix}b=?b0?b1?b2?b3???
  • 向量 c?=(c0c1c2c3)\vec{c} = \begin{pmatrix} c_0 \\ c_1 \\ c_2 \\ c_3 \end{pmatrix}c=?c0?c1?c2?c3???

這里的 a0,a1,…,c3a_0, a_1, \dots, c_3a0?,a1?,,c3? 都是普通的 32 位浮點數。

2. relaxed_madd 的數學公式

v128.relaxed_madd<f32>(a, b, c) 這條指令執行的計算,其結果是一個新的向量,我們稱之為 $ \vec{r} $ (result)。這個計算的數學公式是:

r?=(a?⊙b?)+c?\vec{r} = (\vec{a} \odot \vec{b}) + \vec{c}r=(ab)+c

這里的 ⊙\odot 符號代表 哈達瑪積 (Hadamard Product),也就是分量相乘 (component-wise multiplication)

3. 展開公式,看清細節

把上面的公式展開到每一個分量上,就能看清它到底發生了什么。結果向量 r?\vec{r}r 的四個分量 r0,r1,r2,r3r_0, r_1, r_2, r_3r0?,r1?,r2?,r3? 是這樣并行計算出來的:

r?=(r0r1r2r3)=(a0?b0+c0a1?b1+c1a2?b2+c2a3?b3+c3)\vec{r} = \begin{pmatrix} r_0 \\ r_1 \\ r_2 \\ r_3 \end{pmatrix} = \begin{pmatrix} a_0 \cdot b_0 + c_0 \\ a_1 \cdot b_1 + c_1 \\ a_2 \cdot b_2 + c_2 \\ a_3 \cdot b_3 + c_3 \end{pmatrix}r=?r0?r1?r2?r3???=?a0??b0?+c0?a1??b1?+c1?a2??b2?+c2?a3??b3?+c3???

這就是 relaxed_madd 的全部真相:它在一條指令里,同時并行地完成了這四個獨立的融合乘加運算


它在你的矩陣乘法代碼中是如何被應用的?

現在我們把你代碼中的一行拿出來,用這個公式來解釋:

// 代碼行
res0 = v128.relaxed_madd<f32>(sA0, rB0, res0_prev); 
// (我把之前的 res0 重命名為 res0_prev 以便區分)

這里的輸入是什么?

  • sA0: 這是一個由矩陣 A 的元素 A[0][0] 廣播 (splat) 而來的向量。
    sA0?=(A[0][0]A[0][0]A[0][0]A[0][0])\vec{sA0} = \begin{pmatrix} A[0][0] \\ A[0][0] \\ A[0][0] \\ A[0][0] \end{pmatrix}sA0=?A[0][0]A[0][0]A[0][0]A[0][0]??

  • rB0: 這是矩陣 B 的第一行向量。
    rB0?=(B[0][0]B[0][1]B[0][2]B[0][3])\vec{rB0} = \begin{pmatrix} B[0][0] \\ B[0][1] \\ B[0][2] \\ B[0][3] \end{pmatrix}rB0=?B[0][0]B[0][1]B[0][2]B[0][3]??

  • res0_prev: 這是上一步計算的結果(累加值)。

那么,v128.relaxed_madd<f32>(sA0, rB0, res0_prev) 這一步到底計算了什么?我們套用上面的公式:

res0?=(sA0?⊙rB0?)+res0prev?\vec{res0} = (\vec{sA0} \odot \vec{rB0}) + \vec{res0_{prev}}res0=(sA0rB0)+res0prev??

展開來看就是:

res0?=(A[0][0]?B[0][0]+res0prev,0A[0][0]?B[0][1]+res0prev,1A[0][0]?B[0][2]+res0prev,2A[0][0]?B[0][3]+res0prev,3)\vec{res0} = \begin{pmatrix} A[0][0] \cdot B[0][0] + res0_{prev,0} \\ A[0][0] \cdot B[0][1] + res0_{prev,1} \\ A[0][0] \cdot B[0][2] + res0_{prev,2} \\ A[0][0] \cdot B[0][3] + res0_{prev,3} \end{pmatrix}res0=?A[0][0]?B[0][0]+res0prev,0?A[0][0]?B[0][1]+res0prev,1?A[0][0]?B[0][2]+res0prev,2?A[0][0]?B[0][3]+res0prev,3???

這完美地對應了我們矩陣乘法思想:用 A 的一個標量元素,去數乘 B 的一整個行向量,然后加到累加器上。

當你把四次 relaxed_madd 調用鏈接起來后,最終的結果 res0 的第一個分量就是:
r0=(A[0][0]?B[0][0])+(A[0][1]?B[1][0])+(A[0][2]?B[2][0])+(A[0][3]?B[3][0])r_0 = (A[0][0] \cdot B[0][0]) + (A[0][1] \cdot B[1][0]) + (A[0][2] \cdot B[2][0]) + (A[0][3] \cdot B[3][0])r0?=(A[0][0]?B[0][0])+(A[0][1]?B[1][0])+(A[0][2]?B[2][0])+(A[0][3]?B[3][0])
這正好是結果矩陣 C 的 C[0][0] 元素!其他分量同理。

FMA 的“融合”體現在哪里?

“融合” (Fused) 的意思是,在計算 ai?bi+cia_i \cdot b_i + c_iai??bi?+ci? 時:

  1. 計算 ai?bia_i \cdot b_iai??bi? 的乘積,得到一個內部的、高精度的中間結果(比如 80 位浮點數)。
  2. 不進行舍入,直接用這個高精度結果與 cic_ici? 相加。
  3. 對最終的和只進行一次舍入,得到 32 位的浮點數結果。

相比之下,非融合的 mul + add 會進行兩次舍入,可能會損失精度。更重要的是,FMA 是一條硬件指令,吞吐量更高。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90809.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90809.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90809.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【全新上線】境內 Docker 鏡像狀態監控

境內 Docker 鏡像狀態監控&#xff1a;您的 Docker 加速伴侶 在當今云計算和容器化技術飛速發展的時代&#xff0c;Docker 已成為開發者不可或缺的工具。然而&#xff0c;對于身處國內的用戶而言&#xff0c;訪問境外 Docker Hub 等鏡像倉庫時常會遭遇網絡延遲和連接不穩定的困…

Visual Studio中部署PaddleOCRv5 (借助ncnn框架)

PaddleOCRv5_ncnn PaddleOCRv5 在Visual Studio中進行圖片OCR檢測&#xff08;ncnn框架open-mobile實現)&#xff0c;嘗試對nihui的ncnn-android-ppocrv5檢測算法的剝離與移植。 本項目Github鏈接如下&#xff1a;PaddleOCRv5_ncnn 寫在前面 本倉庫代碼是基于nihui的ncnn-a…

中級全棧工程師筆試題

解釋ACID特性&#xff0c;如何在node.js中實現事務操作針對React單頁應用&#xff0c;請提供至少5種性能優化方案&#xff0c;并解釋其原理&#xff1a; 減少首屏加載時間優化渲染性能資源加載策略狀態管理優化代碼分割方案 如何防止以下攻擊&#xff1a; JWT令牌挾持Graph QL查…

Windows---動態鏈接庫Dynamic Link Library(.dll)

DLL的“幕后英雄”角色 在Windows操作系統的生態中&#xff0c;有一類文件始終扮演著“幕后英雄”的角色——它們不像.exe文件那樣直接呈現為用戶可見的程序窗口&#xff0c;卻支撐著幾乎所有應用程序的運行&#xff1b;它們不單獨執行&#xff0c;卻承載著系統與軟件的核心功…

深入分析計算機網絡傳輸層和應用層面試題

三、傳輸層面試題&#xff08;Transmission Layer&#xff09;傳輸層位于 OSI 七層模型的第四層&#xff0c;它的核心任務是為兩個主機之間的應用層提供可靠的數據傳輸服務。它不僅承擔了數據的端到端傳輸&#xff0c;而且還實現了諸如差錯檢測、數據流控制、擁塞控制等機制&am…

【RH134 問答題】第 2 章 調度未來任務

目錄crontab 文件中的用戶作業時間格式怎么解釋&#xff1f;如果需要以當前用戶身份計劃周期性作業&#xff0c;在上午 8 點到晚上 9 點之間每兩分鐘一次輸出當前日期和時間&#xff0c;該作業只能在周一到周五運行&#xff0c;周六或周日不能運行。要怎么做&#xff1f;要計劃…

【ee類保研面試】通信類---信息論

25保研er&#xff0c;希望將自己的面試復習分享出來&#xff0c;供大家參考 part0—英語類 part1—通信類 part2—信號類 part3—高數類 part100—self項目準備 文章目錄**面試復習總綱****Chap2: 熵、相對熵和互信息 (Entropy, Relative Entropy, and Mutual Information)****…

vue2+node+express+MongoDB項目安裝啟動啟動

文章目錄 準備環境 安裝MongoDB 安裝 MongoDB Compass(圖形化數據庫管理工具) 安裝 Postman(接口測試工具) 項目結構 配置項目代理 項目啟動 提交項目 生成Access Token 準備環境 默認含有node.js、npm 安裝MongoDB 下載地址:https://www.mongodb.com/try/download/com…

JavaEE初階第十二期:解鎖多線程,從 “單車道” 到 “高速公路” 的編程升級(十)

專欄&#xff1a;JavaEE初階起飛計劃 個人主頁&#xff1a;手握風云 目錄 一、多線程案例 1.1. 定時器 一、多線程案例 1.1. 定時器 定時器是軟件開發的一個重要組件&#xff0c;是一種能夠按照預設的時間間隔或在特定時間點執行某個任務或代碼片段的機制。你可以把它想象成…

EDoF-ToF: extended depth of field time-of-flight imaging解讀, OE 2021

1. 核心問題&#xff1a;iToF相機的“景深”死穴我們之前已經詳細討論過&#xff0c;iToF相機的“景深”&#xff08;有效測量范圍&#xff09;受到光學散焦的嚴重制約。問題根源&#xff1a; 當iToF相機的鏡頭散焦時&#xff0c;來自場景不同深度的光信號會在傳感器像素上發生…

符號引用與直接引用:概念對比與實例解析

符號引用與直接引用&#xff1a;概念對比與實例解析 符號引用和直接引用是Java虛擬機(JVM)中類加載與執行機制的核心概念&#xff0c;理解它們的區別與聯系對于深入掌握Java運行原理至關重要。下面我將從定義、特性、轉換過程到實際應用&#xff0c;通過具體示例全面比較這兩類…

每日一講——Podman

一、概念1、定義與定位Podman&#xff08;Pod Manager&#xff09;是符合OCI標準的容器引擎&#xff0c;用于管理容器、鏡像及Pod&#xff08;多容器組&#xff09;。它無需守護進程&#xff08;Daemonless&#xff09;&#xff0c;直接通過Linux內核功能&#xff08;如命名空間…

Spring Boot DFS、HDFS、AI、PyOD、ECOD、Junit、嵌入式實戰指南

Spring Boot分布式文件系統 以下是一些關于Spring Boot分布式文件系統(DFS)的實現示例和關鍵方法,涵蓋了不同場景和技術的應用。這些示例可以幫助理解如何在Spring Boot中集成DFS(如HDFS、MinIO、FastDFS等)或模擬分布式存儲。 使用Spring Boot集成HDFS 基礎配置 // 配…

解決GoLand運行go程序報錯:Error: Cannot find package xxx 問題

問題描述 一個簡單的go程序&#xff0c;代碼如下 package mainimport "fmt" func main() {// 占位符&#xff0c;和java的String.format用法一樣fmt.Printf("我%d歲&#xff0c;我叫%s", 18, "yexindong") }結構如下當我想要運行時卻報錯 Error:…

Spring MVC設計精粹:源碼級架構解析與實踐指南

文章目錄一、設計哲學&#xff1a;分層與解耦1. 前端控制器模式2. 分層架構設計二、核心組件源碼解析1. DispatcherServlet - 九大組件初始化2. DispatcherServlet - 前端控制器&#xff08;請求處理中樞&#xff09;請求源碼入口&#xff1a;FrameworkServlet#doGet()請求委托…

k8s之控制器詳解

1.deployment&#xff1a;適用于無狀態服務1.功能(1)創建高可用pod&#xff08;2&#xff09;滾動升級/回滾&#xff08;3&#xff09;平滑擴容和縮容2.操作命令&#xff08;1&#xff09;回滾# 回滾到上一個版本 kubectl rollout undo deployment/my-app# 回滾到特定版本&…

.NET Core中的配置系統

傳統配置方式文件Web.config 進行配置。ConfigurationManager類配置。.NET配置系統中支持配置方式文件配置&#xff08;json、xml、ini等&#xff09;注冊表環境變量命令行自定義配置源Json文件配置方式實現步驟&#xff1a;創建一個json文件&#xff0c;把文件設置 為“如果較…

kafka的消費者負載均衡機制

Kafka 的消費者負載均衡機制是保證消息高效消費的核心設計&#xff0c;通過將分區合理分配給消費者組內的消費者&#xff0c;實現并行處理和負載均衡。以下從核心概念、分配策略、重平衡機制等方面詳細講解。一、核心概念理解消費者負載均衡前&#xff0c;需明確三個關鍵概念&a…

騰訊云edges on部署pages

騰訊云edges on部署pages適用場景部署方式官方文檔 適用場景 Next.js Hexo 以及用React Vue等現代前端框架構建的單頁應用全棧項目開發 通過Pages Function KV等能力 實現輕量化的動態服務快速部署與迭代 通過Github等代碼管理平臺集成 每次代碼提交時自動構建和部署網站 注…

SpringAI入門及淺實踐,實戰 Spring? AI 調用大模型、提示詞工程、對話記憶、Adv?isor 的使用

上一次寫AI學習筆記已經好久之前了&#xff0c;溫習溫習&#xff0c;這一章講講關于Spring? AI 調用大模型、對話記憶、Adv?isor、結構化輸出、自定義對話記憶?、Prompt 模板的相關知識點。 快速跳轉到你感興趣的地方一、提示詞工程&#xff08;Prompt&#xff09;1. 基本概…