?php/** * * 《计算机体系结构量化研究方法》第7章 领域专用体系结构(DSA) * TPU / 脉动阵列 / 神经网络 概念 312~333 * 大白话讲解 原生PHP可运行代码 * 运行 php D:\1\arch_chapter7.php * * 为什么全用原生PHP不用Swoole? * DSA这章神经网络数学 脉动阵列数据流。 * 脉动阵列和SIMD一样是锁步同步数据流:所有PE每拍同步乘加、传数据。 * 这是确定的逐拍模拟,用真协程反而破坏锁步、看不清数据怎么流。 * */functiontitle($n,$t){echo\n [$n] $t \n;}/* 一些激活函数 */functionsigmoid($x){return1/(1exp(-$x));}functionrelu($x){returnmax(0,$x);}/* 矩阵乘 C A×B */functionmatmul($A,$B){$ncount($A);$mcount($B[0]);$kcount($B);$C[];for($i0;$i$n;$i)for($j0;$j$m;$j){$s0;for($p0;$p$k;$p)$s$A[$i][$p]*$B[$p][$j];$C[$i][$j]$s;}return$C;}/* 312. 领域专用体系结构(DSA)为某一类任务(如神经网络)量身定制的芯片,把通用功能全砍掉。 */functiondemo_312(){title(312,领域专用体系结构 (DSA));echo 通用CPU什么都能干但都不极致; DSA只干一类活(如DNN),却快几十倍、省电几十倍\n;echo 代表:Google TPU(做神经网络)、GPU(做图形/AI)\n;}/* 313. DSA的设计指导原则书里给的5条。 */functiondemo_313(){title(313,DSA 的设计指导原则);foreach([用专用存储器,把数据搬运降到最低,把省下的晶体管投到更多运算单元/更大片上存储,用最契合领域的并行形式,把数据精度降到够用就行(如int8),用领域专用语言(DSL)把程序映射到硬件,]as $i$v)echo .($i1).) $v\n;}/* 314. 专用存储器用软件显式管理的便笺存储器(scratchpad),取代自动但低效的缓存。 */functiondemo_314(){title(314,专用存储器 (Scratchpad));echo 通用CPU用缓存:自动但你管不了,常缺失\n;echo DSA用便笺存储器:编译器显式安排什么时候搬什么数据进来 命中可预测、不浪费\n;// 模拟:把要反复用的权重一次搬进片上便笺,之后全部本地访问$weightsrange(1,8);$scratch$weights;echo 把8个权重一次搬进scratchpad,之后全本地读 不再反复访问慢速主存\n;}/* 315. 减少控制开销砍掉乱序/分支预测/多级缓存这些控制电路,把晶体管让给算力。 */functiondemo_315(){title(315,减少控制开销);echo CPU一大半晶体管在做控制(乱序/预测/缓存管理)\n;echo DSA:任务规律(就是矩阵乘),不需要这些 砍掉,腾出空间堆乘法器\n;}/* 316. 利用领域并行神经网络天生是大规模矩阵运算,并行度极高,硬件直接铺满乘加单元。 */functiondemo_316(){title(316,利用领域并行);echo DNN核心矩阵乘,成千上万个乘加互相独立 铺一大片乘加阵列同时算\n;$size256;echo TPU的乘加阵列{$size}×{$size} 一拍做 .number_format($size*$size). 次乘加!\n;}/* 317. 降低数据精度推理用int8就够,不必fp32 同样面积能塞4倍运算单元、省带宽省电。 */functiondemo_317(){title(317,降低数据精度 (量化));$fp32[0.12,-0.87,1.53,0.05];// 量化到int8: 找缩放因子,把浮点映射到 -127..127 的整数$maxAbsmax(array_map(abs,$fp32));$scale$maxAbs/127;$int8array_map(fn($x)(int)round($x/$scale),$fp32);$deqarray_map(fn($q)round($q*$scale,3),$int8);echo fp32: [.implode(,,$fp32).]\n;echo 量化int8: [.implode(,,$int8).] (缩放因子≈.round($scale,4).)\n;echo 反量化回: [.implode(,,$deq).] (略有误差,但推理够用)\n;echo 好处:8位比32位省4倍存储/带宽,乘法器也小 同面积塞更多\n;}/* 318. 领域专用语言(DSL)用TensorFlow/Halide这种高层语言描述计算,编译器再映射到DSA硬件。 */functiondemo_318(){title(318,领域专用语言 (DSL));echo 程序员写: Y relu(matmul(X, W) b) (TensorFlow风格)\n;echo 编译器负责:把它拆成硬件能执行的矩阵乘/卷积,排好数据搬运 人不用管底层\n;}/* 319. 神经网络基本单元是神经元——把输入加权求和,再过一个激活函数。 */functiondemo_319(){title(319,神经网络 (神经元));$x[1.0,2.0,3.0];$w[0.2,-0.1,0.4];$b0.5;$sum$b;foreach($x as $i$xi)$sum$xi*$w[$i];// 加权求和$outsigmoid($sum);// 激活echo 输入·权重求和偏置 .round($sum,3)., sigmoid后 .round($out,4).\n;echo 一个神经元 点积 激活函数; 神经网络海量神经元堆叠\n;}/* 320. 深度神经网络(DNN)很多层神经元串起来,层数深,能学复杂特征。 */functiondemo_320(){title(320,深度神经网络 (DNN));echo 输入层 - 隐藏层1 - 隐藏层2 - ... - 输出层 (层多深)\n;echo 每层都是一次矩阵乘激活 整个DNN一连串矩阵乘 DSA专攻矩阵乘\n;}/* 321. 多层感知机(MLP)最基础的全连接DNN,每层每个神经元连到上层所有神经元。 */functiondemo_321(){title(321,多层感知机 (MLP 前向传播));$X[[1.0,2.0]];// 1个样本,2维输入$W1[[0.1,0.2,0.3],[0.4,0.5,0.6]];// 2-3$Hmatmul($X,$W1);$H[array_map(relu,$H[0])];// 激活$W2[[0.1],[0.2],[0.3]];// 3-1$Ymatmul($H,$W2);echo 输入[1,2] - 隐藏层(relu) - 输出\n;echo 隐藏层[.implode(,,array_map(fn($v)round($v,2),$H[0])).], 输出.round($Y[0][0],3).\n;echo 全连接层矩阵乘 MLP就是几次matmul叠加\n;}/* 322. 卷积神经网络(CNN)用小卷积核在图像上滑动做局部加权和,擅长图像。 */functiondemo_322(){title(322,卷积神经网络 (CNN 卷积));$img[[1,2,3],[4,5,6],[7,8,9]];// 3x3图$kernel[[1,0],[0,-1]];// 2x2卷积核$out[];for($i0;$i2;$i)for($j0;$j2;$j){$s0;for($a0;$a2;$a)for($b0;$b2;$b)$s$img[$i$a][$j$b]*$kernel[$a][$b];$out[$i][$j]$s;}echo 3x3图 与 2x2核 卷积 2x2特征图:\n;foreach($out as $row)echo [.implode(,,$row).]\n;echo 卷积也能展开成矩阵乘(im2col) 同样落到DSA的乘加阵列上\n;}/* 323. 循环神经网络(RNN)有记忆,当前输出取决于当前输入上一步的隐藏状态,擅长序列。 */functiondemo_323(){title(323,循环神经网络 (RNN));$seq[1.0,0.5,-0.3];$Wx0.6;$Wh0.8;$h0.0;foreach($seq as $t$x){$htanh($Wx*$x$Wh*$h);// 隐藏状态滚动更新echo 时刻{$t}: 输入{$x} 隐藏状态h.round($h,4). (带着上一步的记忆)\n;}echo h_t依赖h_(t-1) 有时间上的循环携带相关 序列建模(文本/语音)\n;}/* 324. LSTM带门的高级RNN,用遗忘门/输入门/输出门控制记忆,解决长序列遗忘问题。 */functiondemo_324(){title(324,LSTM (长短期记忆));// 一步LSTM(单元): 简化标量版$x1.0;$h_prev0.2;$c_prev0.5;$fsigmoid(0.5*$x0.1*$h_prev);// 遗忘门:留多少旧记忆$isigmoid(0.4*$x0.2*$h_prev);// 输入门:进多少新信息$osigmoid(0.3*$x0.1*$h_prev);// 输出门:放多少出去$gtanh(0.6*$x0.2*$h_prev);// 候选记忆$c$f*$c_prev$i*$g;// 更新细胞状态$h$o*tanh($c);// 新隐藏状态echo 遗忘门f.round($f,3). 输入门i.round($i,3). 输出门o.round($o,3).\n;echo 细胞状态c.round($c,3)., 隐藏状态h.round($h,3).\n;echo 门控让信息有选择地长期保留 解决普通RNN记不住远处的毛病\n;}/* 325. 训练与推理训练用海量数据反复调权重(慢、要反向传播);推理用训好的权重做预测(快)。 */functiondemo_325(){title(325,训练与推理);echo 训练: 前向算误差 - 反向传播算梯度 - 更新权重, 反复百万次(算力/精度要求高,常用fp32/16)\n;echo 推理: 权重固定,只做一次前向 快、可低精度(int8) TPU等推理芯片专攻这个\n;// 演示一次梯度下降更新$w0.5;$x2.0;$target1.0;$lr0.1;$pred$w*$x;$grad2*($pred-$target)*$x;$w-$lr*$grad;echo 一步训练:预测.($pred).,误差驱动 权重 0.5 - .round($w,3).\n;}/* 326. 张量处理单元(TPU)谷歌专为神经网络推理造的DSA,核心是个巨大的脉动矩阵乘阵列。 */functiondemo_326(){title(326,张量处理单元 (TPU));echo 核心:256×256的脉动阵列(65536个乘加单元) 大片上权重/激活存储\n;echo 专做矩阵乘,int8精度 神经网络推理上比同期CPU/GPU快几十倍、能效高几十倍\n;}/* ---------- 327. 脉动阵列(本章高潮):逐拍模拟2×2矩阵乘的数据流 ---------- * 输出驻留(output-stationary): PE[i][j]累加C[i][j]. * A从左边流入(行i喂给第i行PE),B从上边流入(列j喂给第j列PE),带斜行(skew)对齐. * 每拍:每个PE把流经的a、b相乘累加,再把a传给右邻、b传给下邻. */functiondemo_327(){title(327,脉动阵列 (Systolic Array, 逐拍数据流));$A[[1,2],[3,4]];$B[[5,6],[7,8]];$n2;$acc[[0,0],[0,0]];// 每个PE的累加器$aGrid[[0,0],[0,0]];// 当前停留在各PE的a值$bGrid[[0,0],[0,0]];// 当前停留在各PE的b值echo 计算 A[[1,2],[3,4]] × B[[5,6],[7,8]], 期望C[[19,22],[43,50]]\n;$cycles2*$n1;for($t0;$t$cycles;$t){// 1) 每个PE乘加for($i0;$i$n;$i)for($j0;$j$n;$j)$acc[$i][$j]$aGrid[$i][$j]*$bGrid[$i][$j];// 2) 数据搬移:a向右、b向下(从远端往边缘倒着搬,避免覆盖)for($i0;$i$n;$i)for($j$n-1;$j0;$j--)$aGrid[$i][$j]$aGrid[$i][$j-1];for($j0;$j$n;$j)for($i$n-1;$i0;$i--)$bGrid[$i][$j]$bGrid[$i-1][$j];// 3) 边缘注入新数据(带skew:行i的A延后i拍,列j的B延后j拍)for($i0;$i$n;$i){$col$t-$i;$aGrid[$i][0]($col0$col$n)?$A[$i][$col]:0;}for($j0;$j$n;$j){$row$t-$j;$bGrid[0][$j]($row0$row$n)?$B[$row][$j]:0;}echo 拍{$t}: 累加器 C[[.$acc[0][0].,.$acc[0][1].],[.$acc[1][0].,.$acc[1][1].]]\n;}echo 最终 C[[.$acc[0][0].,.$acc[0][1].],[.$acc[1][0].,.$acc[1][1].]] (与matmul验证: ;$refmatmul($A,$B);echo($acc$ref?一致✓:不一致✗).)\n;echo 精髓:数据像心跳一样脉动流过阵列,每个数据被复用做很多次乘加 极省搬运、极高吞吐\n;}/* 328. TPU微体系结构矩阵乘单元(MMU脉动阵列) 累加器 激活单元 统一缓冲区,数据流水走一遍。 */functiondemo_328(){title(328,TPU 微体系结构);echo 数据流: 统一缓冲区(激活) - 脉动矩阵乘MMU - 累加器 - 激活/池化单元 - 写回\n;echo 权重从片上权重存储喂进MMU; 整条链像流水线,持续吞吐\n;echo 控制极简:就是反复喂数据、矩阵乘、激活 没有乱序/预测那套\n;}/* 329. Microsoft Catapult用FPGA(可重配置芯片)做加速,灵活、可改逻辑,部署在数据中心网卡旁。 */functiondemo_329(){title(329,Microsoft Catapult (FPGA));echo FPGA可现场重新编程的芯片:介于通用CPU和固定ASIC之间\n;echo 优点:逻辑可改(算法升级不用换芯片); 微软用它加速搜索排序/网络/AI\n;}/* 330. Intel Crest英特尔的深度学习训练专用芯片(Nervana系),为训练优化。 */functiondemo_330(){title(330,Intel Crest);echo Intel收购Nervana后的训练专用DSA,面向DNN训练(高带宽、专用互连)\n;echo 和TPU侧重推理不同,Crest更偏训练这端\n;}/* 331. Pixel Visual Core谷歌手机里的图像处理DSA,用大量小核做图像/视觉计算,低功耗。 */functiondemo_331(){title(331,Pixel Visual Core);echo 手机端图像/视觉DSA:大量简单核组成阵列,专做图像信号处理(HDR等)\n;echo 在手机极有限功耗下,跑得比CPU/GPU快很多、省电很多\n;}/* 332. CPU/GPU/DSA性能对比同一神经网络任务,DSA吞吐远超GPU,GPU又超CPU。 */functiondemo_332(){title(332,CPU / GPU / DSA 性能对比);$perf[CPU1,GPU15,DSA(TPU)70];// 相对吞吐(示意)foreach($perf as $k$v)echo .str_pad($k,10). 相对吞吐 ≈ {$v}×\n;echo 原因:DSA把全部资源都投在矩阵乘上,没有通用包袱\n;}/* 333. DSA的能效优势每瓦能完成的运算,DSA甩开CPU/GPU几十倍——这才是它真正的杀手锏。 */functiondemo_333(){title(333,DSA 的能效优势);$eff[CPU1,GPU10,DSA(TPU)80];// 相对 性能/瓦foreach($eff as $k$v)echo .str_pad($k,10). 相对能效(性能/瓦) ≈ {$v}×\n;echo 根因:1)专用存储器少搬数据 2)低精度int8 3)砍掉控制电路 每瓦干更多有用计算\n;echo 结论:摩尔定律放缓后,为领域定制是继续提升性能/能效的主路\n;}/* 主流程 */for($i312;$i333;$i){$fnsprintf(demo_%d,$i);if(function_exists($fn))$fn();}echo\n 第7章 312~333 演示完毕 \n;