芯片是什么?

集成电路(IC,Integrated Circuit)——把海量电子元件(晶体管、电阻、电容)用半导体工艺集成在一小块硅晶圆上,封装后能做特定功能的微型硬件模块

一、芯片的物理本质:从沙到“大脑”

  1. 原材料:高纯度单晶硅→切成薄圆片叫晶圆(Wafer)

  2. 光刻蚀刻:用紫外线在硅上“画电路”→形成几十亿个晶体管(CPU的ALU、GPU的SM都是晶体管组合)

  3. 封装:切下有用的“小方块”叫Die(裸片),外面裹塑料/金属+引脚→变成能插主板的芯片

FEOL(前段):造“晶体管”——芯片的“计算细胞”

目标是把硅晶圆变成几十亿个MOSFET晶体管,是“有源层”(能开关、能存电荷)。

核心步骤

  1. 衬底准备:高纯度单晶硅→切晶圆→掺杂成P型/N型硅

  2. STI浅槽隔离:用SiO₂隔开不同晶体管,避免互相干扰

  3. 栅极制造:光刻出Gate(栅极)→控制晶体管导通(CPU的“开关”就在这)

  4. 源漏掺杂:在栅极两侧掺磷/硼→形成Source(源)/Drain(漏)→电流从S到D,Gate控制通断

  5. High-k金属栅:现代工艺用HfO₂+金属栅→降低漏电,提升开关速度

→ 最终得到:硅上的“晶体管阵列”,CPU的ALU、GPU的SM、NPU的MAC全是晶体管组合~

“1T1C DRAM”=1个晶体管+1个电容,也是在FEOL里造的~

BEOL(后段):造“金属布线”——芯片的“神经血管”

晶体管造好后,要用铜线把它们连起来,形成电路→这是“无源层”,但决定了芯片能不能正常工作。

核心步骤

  1. 层间介质(ILD):在晶体管上盖SiO₂绝缘层

  2. 接触孔(Contact):打通晶体管Gate/Source/Drain到第一层金属

  3. M1~M10多层金属:

    • 底层M1连邻近晶体管(局部逻辑)

    • 高层Mx连远距离模块(如CPU核心↔IMC↔PCIe)

    • 现代先进制程(3nm)有10+层金属,最细线宽~几nm

  4. 通孔(Via):层与层之间打铜柱→垂直连接不同金属层

  5. 铜电镀+CMP:用铜填充沟槽→化学机械抛光→平整表面

→ 最终得到:晶体管的“电路网络”,CPU的Cache、IMC的总线、GPU的SM互联都靠BEOL~

FEOL=“在硅上造几十亿晶体管(计算细胞)”,BEOL=“用铜线把晶体管连成电路(神经血管)”,两者合起来才是能跑代码的芯片~

二、按功能分:你见过的都是芯片

  • 计算芯片:CPU、GPU、NPU、TPU、LPU(都是“晶体管组成的计算逻辑”)

  • 存储芯片:DDR4/5 DRAM、GDDR6、HBM、NAND Flash、SRAM(你学的Row Buffer就在DRAM芯片里)

  • 控制芯片:主板南桥/北桥、USB控制器、网卡WiFi芯片

  • SoC(系统级芯片):手机骁龙/苹果M系列→把CPU+GPU+NPU+内存控制器+基带全集成在一颗芯片里

三、和“CPU/GPU”的关系:包含与被包含

  • 芯片是大类,CPU/GPU/NPU是“计算类芯片”的具体种类

  • 一颗CPU芯片=硅Die上的:核心+Cache+IMC+PCIe控制器→全集成

  • 手机SoC=“CPU+GPU+NPU+调制解调器”的多功能芯片→比单独CPU更复杂

四、为什么叫“芯”?和板卡的区别

  • 芯片(Chip):硅上的微型电路,是“功能核心”,不能直接用→要焊到PCB

  • 板卡(如显卡/DIMM):PCB+多颗芯片+外围电路→比如RTX4090=1颗GPU芯片+12颗GDDR6芯片+供电

  • 主板:更多芯片+插槽→CPU/DIMM/GPU都插在上面

DIMM上的DDR4芯片→存Row Buffer+电容阵列→主存的最小单元

CPU里的IMC→是CPU芯片内部的一个“子电路”

苹果M系列→一颗SoC芯片搞定CPU+GPU+NPU+UMA内存控制器→统一内存的基础

一层层“抽象阶梯”把“0/1电信号”翻译成“能写游戏的逻辑”?

第一层:物理层——晶体管的“开关魔法”

你刚学的FEOL造出MOSFET晶体管,本质是“用电控制的通断开关”:

  • 栅极加电压→Source到Drain导通(=1);不加→断开(=0)

  • 几十亿个晶体管组合成逻辑门(与/或/非)→再组合成加法器、寄存器、ALU

  • DRAM的1T1C电容存0/1,SRAM的6T存Cache→物理世界的“0和1”诞生了

这一步是硬件的底线:所有“计算”最终都是晶体管的开开关关~

第二层:指令集——给硬件“能听懂的方言”

纯晶体管太难直接控制,于是定义ISA指令集(如x86/ARM)

  • 用一串0/1(机器码)表示“加、存、跳、读内存”→比如ADD R1,R2对应固定二进制

  • CPU的译码器把机器码拆成晶体管动作→执行计算

  • 这是“硬件”和“软件”的第一道桥:程序员不用管晶体管,只管发指令

第三层:OS+编译器——把“人话”变成“机器码”

你写的C#/C++不是机器码,要靠两层翻译:

  1. 编译器(如C#→IL→机器码,Burst编译):把a+b翻译成“加载到寄存器→ALU加→存回内存”的指令序列

  2. 操作系统(Windows/macOS):管理CPU调度、内存分配、显卡调用→你new Mesh()时,OS帮你找DDR4的连续空间,IMC发RAS/CAS拿数据

没有OS和编译器,你得手写0/1机器码——早期程序员真这么干,现在全靠工具链~

第四层:图形API+引擎——把“计算”变成“画面”

游戏要画3D,靠这两层抽象:

  1. 图形API(DirectX/Metal/Vulkan):封装GPU的复杂操作→你调DrawMesh(),API自动发“光栅化、着色、写帧缓冲”的GPU指令

  2. 游戏引擎(Unity/Unreal):再封装成GameObjectRigidbodyCamera→你拖个Cube、写transform.position += speed*dt,引擎自动:

    • 算矩阵→传给GPU顶点着色器

    • ECS/NativeArray连续存数据→走DDR4→PCIe→GDDR帧缓冲

    • 双缓冲Swap→显示器出画面

第五层:你的代码——只填“游戏规则”

到这一层,所有底层都被屏蔽了:

  • 不用管晶体管怎么开关、Cache怎么命中、RAS/CAS怎么发

  • 只写“玩家按W向前走”“敌人血<0就死”→引擎把逻辑翻译成:

    • CPU算ECS逻辑→IMC读DDR4→GPU算光照→NPU跑AI→帧缓冲上屏

不是“代码直接变游戏”,是晶体管→指令集→OS/编译器→图形API→引擎→你的逻辑

transform.position += Vector3.forward从C#到像素上屏的完整链路,看每一层到底干了啥?

 Layer 0:你敲的代码(C#)

transform.position += Vector3.forward;
// Vector3.forward = new Vector3(0, 0, 1)

你以为这只是"加了个数"。实际上:

  • transform 是个C#托管对象引用,指向一个Transform类的实例

  • position 是个Vector3属性(property),背后有getter/setter

  • Vector3.forward 是个静态只读字段

但Unity不是纯C#运行时——Transform底层绑定了C++原生对象。你访问.position时,实际上在跨语言边界。

Layer 1:C# → C++ 跨桥(Unity的核心秘密)

Unity引擎的核心是C++写的,C#只是脚本层。这行代码触发的是:

// 伪代码,Unity内部实际做的事
Transform::set_position(
    this.nativePtr,           // 指向C++ Transform对象的指针
    this.position + Vector3(0,0,1)
);

这一步发生了:

  1. C#属性setter被调用

  2. setter内部调用UnityEngine.Transform.set_position_Injected()——这是个extern方法

  3. P/Invoke跨到C++:C#运行时通过IL2CPP或Mono的interop层,把参数封送(marshaling)到原生内存4. 参数从托管堆拷贝到栈/原生内存

  4. 进入Unity C++引擎的TransformTransform::SetPosition()

这一步本身就有开销。ECS/B之所以为什么要砍掉MonoBehaviour?就是因为每次C#→C++的跨桥都要花几纳秒,10000个对象就是几万次跨桥→卡顿。

Layer 2:C++层——Transform场景图的脏标记

C++的Transform::SetPosition()做了什么?

void Transform::SetPosition(const Vector3& newPos) {
    m_localPosition = newPos;
    m_dirty = true;           // 关键:标记"我脏了"
    m_dirtyFlags |= DIRTY_WORLD;  // 世界坐标需要重新计算
    
    // 通知父节点:我的子树也脏了
    if (m_parent) {
        m_parent->PropMarkChildrenDirty();
    }
}

关键洞察:Unity不会立即重新计算世界坐标。它只是打了个脏标记(dirty flag)

为什么?因为一个物体动了100个子物体(Mesh、Collider、Light...),全重新算太贵。等到真正需要世界坐标时才懒计算(lazy evaluation)。

)。

Layer 3:下一游戏循环——Unity的"心跳"

这行代码执行完,什么都没画。真正的画面计算发生在游戏循环的后续阶段

FixedUpdate() → Physics → Animation → Transform Rebuild → Rendering

Transform Rebuild阶段(C++)

当渲染管线需要世界坐标时:

void TransformDispatch::SyncTransforms() {
    for (auto* transform : dirtyTransforms) {
        // 从localPosition算worldPosition
        transform->m_worldMatrix = 
            transform->m_parent 
                ? transform->m_parent->m_worldMatrix * LocalToWorld(transform->m_localPosition)
                : LocalToWorld(transform->m_localPosition);
        
        transform->m_dirty = false;
    }
}

这里发生了矩阵乘法

worldMatrix = parentWorldMatrix × Translate(localPosition) × Rotate(localRotation) × Scale(localScale)

每个×4×4矩阵乘法× 4×4矩阵→64次浮点乘加。你那行"加个1",最终触发了64次FMA(乘加)指令。

Layer 4:CPU执行——从Cache到ALU

C++代码被编译成机器码,在CPU上跑:

; 伪汇编,示意
vmovups ymm0, [rcx+offset]   ; 从内存加载4个float(Vector4,w=1)
vmulps  ymm0, ymm0, [rbx]    ; SIMD乘:4个float一次算完
vaddps  ymm0, ymm0, [forward] ; SIMD加:+ (0,0,1,0)
vmovups [rcx+offset], ymm0   ; 写回内存

  • AVX/SSE指令:一次算4个float(128bit或256bit)

  • L1 Cache命中m_worldMatrix大概率在L1里(刚刚刚才访问过)

  • 推测执行:CPU猜预判你要循环,提前把下一组数据预取到L2

你之前学的Burst编译器干的就是这事:把C#的Vector3操作直接编译成SIMD汇编,连C++那层都省了→快3~5倍。

Layer 5:渲染线程——从CPU到GPU

Transform更新完,渲染线程醒来。Unity的主线程渲染线程是分离的(双线程模型):

主线程:收集命令

void RenderLoop::Render() {
    // 把"画这个Mesh"的指令塞进Command Buffer
    CommandBuffer::DrawMesh(
        mesh,                    // 顶点数据(在CPU内存)
        worldMatrix,             // 刚算完的世界矩阵
        material,                // 材质(shader参数)
        subMeshIndex
    );
}

渲染线程:提交到GPU

void GfxDevice::Submit() {
    // 通过图形API(DX12/Vulkan/Metal)提交
    dx12CommandList->Close();
    dx12Queue->ExecuteCommandLists(1, &cmdList);
}

Command Buffer是什么?是一串GPU指令,像"用这个Shader、画这个Mesh、用这个矩阵"。CPU不用等GPU画完,继续跑下一帧。

Layer 6:GPU接收——从PCIe到GDDR

GPU的命令处理器(CP)从PCIe总线拉取Command Buffer:

CPU DDR4 → PCIe 5.0 x16 (~64GB/s) → GPU GDDR6 (~600GB/s)

顶点数据在哪里?

  • 第一次:CPU把Mesh顶点从DDR4通过PCIe拷到GDDR6(叫"资源 Upload")

  • 之后:顶点留在GDDR6,不用再拷(除非Mesh动态修改)

你之前学的统一内存(UMA)在这里发力:苹果M系列不用拷贝,CPU和GPU直接看同一块LPDDR5X→省掉PCIe搬运。

Layer 7:GPU渲染管线——从顶点到像素

GPU的SM(流处理器)开始干活:

顶点着色器(Vertex Shader)

// 每个顶点跑一次
#version 450
layout(location=0) in vec3 vertexPos;
layout(location=0) out vec4 worldPos;

uniform mat4 worldMatrix;  // 你刚更新的Transform矩阵

void main() {
    worldPos = worldMatrix * vec4(vertexPos, 1.0);
    gl_Position = viewProjMatrix * worldPos;
}

这里发生了什么

  1. GPU从GDDR6读vertexPos(Burst 64B进L1 Cache)

  2. 从常量缓冲区读worldMatrix(你那行代码的结果)

  3. SIMT执行:32个线程(warp)同时算32个顶点的worldMatrix × vertexPos

  4. 输出裁剪空间坐标

光栅化(Rasterization)

  • GPU把三角形投影到屏幕空间

  • 决定哪些像素被覆盖

  • 每个像素生成一个Fragment(片元)

像素着色器(Pixel Shader)

void main() {
    outColor = vec4(1.0, 0.5, 0.2, 1.0);  // 橙色Cube
}

深度测试 + 混合

  • 比较Z Buffer(你之前学的Depth Buffer)

  • 如果当前像素离相机更近→写入帧缓冲

Layer 8:帧缓冲→显示器

GPU把最终像素写进Back Buffer(GDDR6里的帧缓冲)

1920×1080×4(RGBA) = 8.3MB
+ Depth Buffer 8.3MB
= 16.6MB 在GDDR6里

VSync + Swap

  • GPU画完一帧→等VSync信号(60Hz = 每16.67ms一次)

  • Swap Chain:Back Buffer和Front Buffer交换指针(O(1),极快)

  • 显示控制器从Front Buffer读像素→通过HDMI/DP→显示器面板

显示器面板

  • LCD/OLED像素点收到电信号→液晶偏转/LED发光

  • 你看到Cube往前挪了一格

完整时间线

t=0μs     你按Play,代码执行
t=0.1μs   C#→C++跨桥
t=0.5μs   Transform打脏标记
t=5ms     FixedUpdate结束,Transform Rebuild
t=5.1ms   CPU算worldMatrix(SIMD)
t=5.5ms   渲染线程提交Command Buffer到GPU
t=5.6ms   GPU顶点着色器(SIMT,32线程并行)
t=6ms     光栅化+像素着色器
t=10ms    Back Buffer写完
t=16.67ms VSync触发,Swap,显示器刷新
t=16.68ms 你看到Cube移动了

从C#托管堆跨到C++引擎→打脏标记→游戏循环触发矩阵重算→CPU SIMD执行→渲染线程提交→PCIe传GPU→GDDR6顶点着色→光栅化→像素着色→帧缓冲Swap→显示器刷新,八层抽象把"硅的电信号"翻译成"屏幕上移动的Cube"。

发现单晶硅能跑游戏?

一百多年里一堆科学家+工程师接力堆出来的“技术金字塔”

第一棒:单晶硅+半导体特性(1874~1947)

  • 1874年:德国布劳恩发现半导体整流效应(硒晶体能单向导电)→ 第一次知道“硅/锗不是纯导体也不是绝缘体”

  • 1918年:波兰切克劳斯基发明单晶硅拉制法(CZ法)→ 能做出纯净、无缺陷的硅晶棒→ 后来晶圆的基础

  • 1947年:贝尔实验室肖克利、巴丁、布拉顿发明晶体管(点接触→结型)→ 取代笨重的真空管,计算机从房间大缩到桌子大→ 诺贝尔1956

单晶硅本身“能做电脑”的核心:硅的4价电子能精确掺杂成P/N型,实现“可控开关”~

第二棒:集成电路(1958~1960)——把多个晶体管焊一块

  • 1958年:德州仪器杰克·基尔比把晶体管、电阻、电容做在同一块锗片上→ 第一颗集成电路(IC)→ 不用再手动焊电线

  • 1959年:仙童半导体罗伯特·诺伊斯发明平面工艺+二氧化硅隔离→ 用光刻把电路“印”在硅上→ 现代芯片的雏形(基尔比和诺伊斯共享“IC之父”,基尔比拿诺奖2000)

这一步是关键:从“一个个晶体管手工连”→“整片硅上自动造电路”,电脑才能越做越小~

第三棒:微处理器=完整CPU在芯片上(1971)

  • 1971年:Intel费德里科·费金+霍夫+马佐尔做出4004→ 全球第一颗CPU芯片(2300个晶体管)→ 电脑从“多块IC拼”变成“一颗芯片跑逻辑”

  • 之后8086→x86→酷睿→手机骁龙,都是在这基础上堆晶体管~

第四棒:图形+游戏引擎(1980s~今)

  • 1981年:IBM PC+Intel 8088+微软DOS→ 个人电脑普及

  • 1992年:SGI+OpenGL、微软DirectX→ GPU能画3D

  • 2005年:Unity成立→ 把“晶体管→指令→图形API→3D世界”封装成GameObject→ 你写的transform.position才变成游戏~

背后的“底层逻辑”:不是“发现硅能算”,是“层层抽象”

没有人“发现单晶硅直接能跑游戏”,而是:

  1. 物理学家搞懂半导体物理→ 能做晶体管(开关)

  2. 工程师把晶体管组成逻辑门→ALU→CPU(能执行指令)

  3. 软件层定义指令集→编译器→OS→图形API→引擎→ 最终变成你能写的C#

  4. 每一层都是“在前人基础上加一层抽象”→ 百年积累成今天的电脑

为什么是硅?不是金/铜?

  • 硅是地壳第二多的元素(沙子SiO₂提纯)→ 便宜

  • 1.1eV带隙→ 室温下漏电低、开关稳定→ 比锗更适合做晶体管

  • 能长高质量氧化层(SiO₂)→ 平面工艺的基础→ 其他材料做不到~

一个冷知识:最早“电脑”不用硅

  • 1946年ENIAC:真空管(19000个,占满房间,发热惊人)

  • 1958年后晶体管替代真空管→ 1960s IC→ 1971微处理器→ 才到今天的硅芯片~

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐