Tech

Piece of Mind

简单逼自己学点东西。

如何理解GPU的并行 (parallelism)

Feb 12, 2025

  1. SIMD 数据级并行Single Instruction, Multiple Data
    • 一条指令可以同时作用于多个数据 – 例如在图形渲染中,同一个着色器程序可以同时应用于数百万个像素 – 具体而言就是一个线程束中的所有线程都会执行相同的指令
    • 硬件实现:1 – 存储:宽寄存器(256位,可以存储8个32位浮点数) ;2 – 计算:多个并行执行单元,可同时对多个数据进行相同操作;3 – 指令集:向量指令集(如Intel的SSE、AVX,ARM的NEON)
    • 举例:在图形渲染中经常需要对每个像素进行相同的操作(例如亮度调整) – 图像的像素值存储在一个数组向量中,使用一条指令即可实现每个像素亮度+10
  2. 线程级并行(Thread-level parallelism)
    • 软件实现:GPU将任务分解为大量线程,每个线程处理一小部分数据。这些线程被分组为线程块(Thread Blocks),编程模型(如CUDA、OpenCL)为开发者提供了将任务分解为线程和线程块的工具。
    • 硬件实现: 线程块由SM/CU调度执行。与CPU的少量核心(通常4-16个)相比,一个GPU通常包含数千个流处理器或CUDA核心,可以同时处理大量简单的计算任务。
    • 举例:假设有一个向量加法任务:C = A + B(1024),开发者决策定义每个线程处理一个元素(即C[i] = A[i] + B[i]),将线程分组为128个线程的线程块,整个任务包括8个线程块;GPU将其分配给可用的的SM/CU, 每个SM将线程块中的线程划分为线程束(比如32个线程warp)
    • 具体执行方式:SM可以在一个线程束等待内存访问时切换到另一个线程束执行计算 – 所谓”切换“,指每个线程束的寄存器状态和指针指令会分别被寄存器和线程束调度器保存,而当前侧到一个线程束进入内存访问时,调度器会切换到另一个线程束,恢复其指令指针和寄存器状态,继续执行其指令

编程语言的简单对比

Feb 13, 2025

也是在学习了一些assembly/一点点C/一些python/很多Java之后才理解编程语言的差异

编程语言抽象级别语法复杂度硬件控制内存管理性能开发效率
含义语言相对于硬件的抽象程度语法是否简单直观,代码量少,学习门槛低允许开发者控制硬件的能力,如直接访问内存、寄存器、处理器指令等是否要求开发者手动管理内存程序执行的效率,通常低级语言更高,但会增加开发难度使用语言进行开发、调试和维护代码的速度,与语言的抽线和工具支持相关
机器语言极低极低(仅有0/1)完全控制
每条指令对应硬件指令
手动管理(直接操作寄存器)极高(直接控制硬件)极低(编写困难,调试难度大)
汇编语言高(需要详细描述每条指令,操作寄存器和内存)
直接操作寄存器、内存地址
手动管理(需要开发者手动分配和释放内存)高(直接操作硬件,效率高)较低(较低的抽象级别,开发难度高)
C语言中低中等(相对简洁,但涉及指针和内存管理)
通过指针操作内存
手动管理(开发者需要显式分配和释放内存)高(较接近硬件,效率高)中等(语言功能丰富,调试较困难)
C++语言中低高(需要使用类、模板等,代码量大)
指针和内存控制
手动管理(与 C 类似,但引入了更多内存管理工具)高(面向对象特性加成,但性能近似 C)中等(功能丰富,但增加复杂度)
Java语言中等(更简洁,但需要引入库和类)中等
通过 JVM 管理硬件访问
自动垃圾回收(JVM 自动处理内存管理)中等(JVM 中间层可能影响性能)高(开发者不需关心内存管理,拥有大量的库和工具支持)
Python语言低(简洁直观)
完全由操作系统管理硬件
自动垃圾回收(Python 内建垃圾回收机制)中低(解释性语言,执行速度较慢)极高(语法简单,库丰富,开发速度快)
JavaScript低(简洁直观)极低
浏览器内执行,无直接硬件控制)
自动垃圾回收(JS 引擎自动管理内存)中等(适合前端开发,但性能受限于浏览器)极高(用于 Web 开发,生态庞大,快速开发)
高级脚本语言极高非常低(极简语法)极低
通常仅通过高级 API 访问硬件
自动垃圾回收(内建机制)低至中等(牺牲性能换取开发效率)极高(极简的语法和工具支持,适合快速开发)

编程模型 CUDA、OpenCL

February 14

编程模型是一种抽象框架,为开发者提供描述和组织程序的执行逻辑的方式,并规定了这些单元如何交互和协同工作。在GPU编程中,CUDAOpenCL是两种常见的编程模型,在并行计算环境中,编程模型定义了如何将任务分解为多个并行单元(如线程、线程块等)

OS: 其实在java编程中体现了很多共同的思想,例如threads/sync/itonic mechanism

任务分解内存模型同步机制
定义描述如何将任务划分为多个并行单元,也即程序的基本执行单元(如线程、线程块)定义并行单元如何访问内存(如全局内存、共享内存)提供并行单元之间的协调方式(如屏障同步、原子操作)
CUDA by Nvidia
(Compute Unified Device Architecture)
开发者需要将任务分解为多个线程和线程块,比如对于一个向量加法任务,可以将每个元素的计算分配给一个线程,将线程分组为线程块
线程(Thread):最基本的执行单元,每个线程执行相同的代码,但处理不同的数据。
线程块(Thread Block):一组线程的集合,线程块内的线程可以协作(如通过共享内存)。
网格(Grid):一组线程块的集合,网格中的所有线程块执行相同的核函数(Kernel)
全局内存:所有线程都可以访问的内存,容量大但延迟高。
共享内存:线程块内共享的内存,容量小但速度快。
寄存器:每个线程私有的内存,速度最快。
线程块内同步:通过__syncthreads()实现线程块内所有线程的同步。
原子操作:用于避免多个线程同时访问同一内存地址时的冲突。
OpenCL
(Open Computing Language), 跨平台,支持多种硬件, incl. GPU/CPU/FPGA
工作项,工作组,NDRange
对应线程,线程块,网格
工作组内同步:通过barrier()实现工作组内所有工作项的同步。
原子操作:用于避免多个工作项同时访问同一内存地址时的冲突。
备注:1)核函数是在GPU上执行的函数,由多个线程并行执行。开发者通过调用核函数来启动并行任务。

我们这里提到的”开发者“是GPU芯片的使用者,也就是软件开发人员或者研究人员,利用GPU进行编程,来解决实际问题。而英伟达/AMD的工程师,作为硬件和底层软件的开发者,任务是设计和优化GPU芯片及其配套软件:
硬件设计:设计GPU的架构(如SM、CUDA核心、内存层次结构)和优化硬件性能(如提高计算吞吐量、降低功耗)。
驱动开发:开发GPU驱动程序,使操作系统和应用程序能够与GPU通信。
编译器开发:开发编译器,将高级语言代码(如CUDA C++)编译为GPU可执行的指令。
工具开发:开发调试工具(如Nsight)、性能分析工具(如nvprof)和库(如cuBLAS、cuDNN)。

芯片的主频是什么

February 15

  • 定义:clock speed, 处理器的时钟速度,指的是每个核心在一秒内能完成的指令周期数,用GHz(千兆赫)表示
  • GPU和CPU主频:
    • CPU通常拥有更高的主频(2-5GHz),因为用于执行复杂、依赖性(顺序性)强的任务,比如串行计算,保证每个核心单独处理复杂指令时更高效
    • GPU一般只需要1-2GHz,因为设计目标时并行化处理大量简单任务而不是单个核心高速执行。
  • 主频提高的限制:
    • 芯片制程:晶体管尺寸缩小 – 电流流动的距离缩短 – 信号传播更快 – 更高主频
    • 功耗和散热:和主频的平方/立方呈线性关系
    • 物理限制:电子流动速度加快,对晶体管内部的金属通路产生“电迁移”效应,长时间可以导致金属导线被腐蚀
    • 量子效应:量子效应(如隧穿效应)开始显著影响晶体管的工作。电子会“穿透”绝缘层,导致意外电流泄漏,进而引发计算错误。
  • 主频提高的方式:现代芯片设计更倾向于通过增加核心数量和并行处理来提高性能
    • 缩小芯片制程:除了最基础的影响之外,还可以减少传统的开关时栅极的电流泄露(Gate Leakge)降低功耗、缓解电迁移效应从而延长寿命。
    • 新型半导体:如硅锗(SiGe)和碳纳米管(CNTs)等材料的引入,可以降低晶体管内的电阻,减少电流损耗,支持更高的主频。

冯 · 诺伊曼结构

Feb 15

Tmr’s task: let’s 温习一下transformer的结构

回顾一下已忘光的课程笔记 + 学习一下小红书搜刮来的新笔记

### **Nvidia valuation的核心问题** ***Feb 24*** 核心问题:我们到底需要多少算力?计算工具的效率与需求达到均衡的情况下算力的合理价格是什么?Nvidia的壁垒能否让其长期保持收取高于合理价格的溢价的能力? ### **RAG 检索增强技术** ***Feb 25*** Retrieval-Augmented Generation: 当用户向 LLM 提问时,AI 模型会将查询发送给外部知识库,将检索到的信息与输入结合,生成更准确的回答。 **流程:** | **阶段** | **步骤** | **描述** | |——————|———————————–|————————————————————————-| | **输入处理** | 切分 | 将输入文本切分为句子、短语或关键词。 | | | 编码 | 使用编码器(如BERT)将切分后的文本转换为向量表示。 | | **检索阶段** | 向量检索 | 将编码后的输入向量与知识库中的文档向量进行相似度计算,通常使用余弦相似度。 | | | Top-K检索 | 选择相似度最高的K个文档或段落作为候选。 | | **生成阶段** | 上下文编码 | 将检索到的文档与原始输入结合,再次编码为上下文向量。 | | | 解码生成 | 使用解码器(如GPT)根据上下文向量生成最终输出。 | **Note**: 外部知识库只是额外inputs,所以不需要进行训练。但在高级实现中,检索模块和生成模块可以联合训练。 作为一种技术,它一定有**门槛**: | **门槛** | **关键点** | **描述** | |——————|———————————–|————————————————————————-| | **检索系统构建** | 高效检索大规模知识库 | 需要支持快速检索大规模外部知识库(如维基百科、专业数据库)。 | | | 快速向量相似度计算 | 检索系统需支持快速向量相似度计算(如使用FAISS、Annoy等近似最近邻搜索工具)。 | | **模型集成** | 检索与生成模型结合 | 需要将检索模块与生成模型(如GPT、T5等)无缝结合。 | | | 输入输出对齐 | 检索和生成模块的输入输出需对齐,确保信息传递一致。 | | **计算资源** | 高性能硬件支持 | 检索和生成过程需要大量计算资源,尤其是处理大规模知识库时。 | | | GPU/TPU支持 | 需要高性能硬件(如GPU/TPU)支持。 |

Discover more from Christina's World

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *