分享到plurk 分享到twitter 分享到facebook

LIAO-JIAN-PENG (廖健棚)

簡介

2024 Linux 核心設計 春季班 自我評量

成果發表和貢獻

你所不知道的 C 語言:記憶體管理、對齊及硬體特性:補上中英之間的空白字元
雖然只是補上空白,但是我知道注重細節很重要,從細節可以看出一個人的專業素養,也能提升整體工作的品質與效率。 給自己 3 分。

作業/隨堂測驗

在 Lab 0 中,我實作了基本的佇列操作以及合併排序(Merge Sort) 和快速排序(Quick Sort) 的排序演算法。同時,在撰寫作業的開發過程中,我發現翻閱自己過去所學的計算機組織、資料結構、演算法等相關書籍,而過程中我補足自己所缺漏的部分。另外我也學會翻閱 C 語言規格書及 GCC 手冊,查看第一手的資訊。此外,作業中一直強調使用正確的資訊科技詞彙,工程人員不僅僅是寫程式,更多時間是用來做溝通。如果在溝通過程中使用含糊不清的詞彙,會導致對話中的誤會和阻礙。因此,我在用詞之前,會確認自己的用詞是否精確。

我給自己 8 分。

期末專題

Linux 核心專題: llama.cpp 效能分析
在核心專題中,我整理了矩陣乘法的加速手法,探討了經典的矩陣加速演算法(Strassen algorithm)。另外,我重現了專案 matmulmatmul_bench 的加速手法,分析了其中讓矩陣相乘加速的方法。這些方法包括增加快取存取的效率及使用 SIMD 技巧來提升速度。

在增加存取效率方面,將第二個矩陣在相乘前進行轉置,使其轉換為列優先存取模式,能有效提升快取命中率。在 2048x2048 的矩陣相乘中,比原始方法快了 5 倍。另外,透過 loop interchange 的技巧,利用空間局部性的特性減少了 cach-miss 次數,提升了存取效率。,使得在相同的 2048x2048 矩陣相乘中,比原始方法快了 8 倍。

隨著大規模的矩陣相乘,使用 loop unrolling 及 block matrix multiplication 可以將計算分割成較小的區塊,並完全容納於快取中,有效提升記憶體存取速度。最後,在 SIMD 的效能比較中,我使用了 Intel 所推出的 SSE、AVX 及 FMA 做資料的平行化處理,並在 2048x2048 矩陣相乘中,最快的方法比原始方法快了 14 倍。

在語言模型的量化過程中,會將浮點數(Floating Point)資料縮小到定點數(integer)的範圍,不僅減少了模型的記憶體需求,也提升了推算速度。浮點數數據型態通常佔用較大的記憶體空間,如 32 位元的單精度浮點數(FP32)或 64 位元的雙精度浮點數(FP64),相較之下,定點數(Integer)數據型態佔用的記憶體空間較小,如 8 位元的整數(INT8)。在固定的記憶體頻寬下,較小的數據型態可以使更多的數據在同一時間內傳輸,提升模型的推算速度。浮點數轉換為定點數後,模型的參數體積大幅縮小,減少了對記憶體的需求。現代 CPU 和 GPU 對於定點數的計算通常有更高的效能,因為定點數運算比浮點數運算更簡單且所需的計算資源更少,使用定點數可以更快地完成計算,提升整體模型的推算速度。除了運用量化模型,我也會試著推導量化的過程,涵蓋矩陣相乘的量化及 ReLU 的量化,理解量化實做的過程。

我給自己 9 分

與授課教師的互動

  • 5/1 下午8:30 與授課老師一對一討論

一對一討論中,老師用一些非常簡單的蓋念告訴我說科普與專家的差別在哪,科普是用簡單易懂的方式傳達知識,而專家是可以讓公司掏錢請你去解決問題,老師在意的是後者。我要能夠解決問題,只會科普知識並不足以解決,因為真實世界的問題是很困難,很不容易處理,沒有嚴謹的解決流程以及不斷的做實驗並分析數據,根本就沒辦法觀察問題本身,何況是要解決問題,如果可以用科普的知識解決問題,那就意味著這個問題太簡單。因為身為工程人員,最重要的使命應該是要去解決沒人解決的問題,我們應該都要對自己有這樣的期待。

我給我自己 8 分

所見所聞所感

授課老師在第一週時便提到,這堂課雖然是 3 學分,但實際上可以當作 9 學分。從第一週開始,老師所派的作業 lab0-C 以及每週需要閱讀的教材,讓我了解到這是一門不簡單的課程,且需要誠實面對自己。誠實有多困難,我從作業一的開發紀錄中體會到,將翻譯內容貼上,才發現自己正在舉燭,並未真正理解英文背後的含義,以為翻譯後就欺騙自己看懂了。因此,在後續的作業及專題中,我明白自己在貼上內容前,必須先找到第一手教材,並完整閱讀與理解其原理。我發現,雖然單字都能看懂,但合在一起卻不理解其含意,這也讓我意識到自己基礎知識的不足,需要大量的背景知識才能理解其中的含義。

這也是為什麼老師強調,前六週的課程與 Linux 核心無關,而是對資訊素養的鍛鍊。在這巨量的教材中,我學到了指標的操作(如何透過 indirect pointer 消除特例)、bitwise 操作(直接對位元進行位移及邏輯操作以提升效能)。此外,在課堂問答中被問到什麼是 in-place algorithm,讓我了解為什麼在 Linux Kernel 中特別注重它,也進而認識了動態配置記憶體的存取方式,如 First-fit 和 Best-fit。

雖然在學期中後期,時間較為緊迫,加上實驗室的計畫無法像學期初一樣大量時間投入,但在與老師一對一討論後,我決定後期專題做與實驗室相關的內容(llama.cpp 效能分析)。我清楚這是一個前人未曾涉足的題目,因此可參考的資訊有限,但最終我還是在有限的時間內,探討了矩陣運算的方法及量化模型降低精度以提高模型的吞吐量。

最後,回應我在作業五中說的話:「選了,就好好走,不要浪費時間在猶豫或後悔上。」我沒有辜負兩個月前的自己,我依然在這條學習的路上堅持著。

我給自己 9 分

研究生發信

  • 二月份回顧信件(3/1): 撰寫 git commit message, 理解 linked list 和非連續記憶體的操作,回顧作業系統術語及概念,探究一些問題如 「如何偵測 linked list 是否存在環狀結構?」和「如何對 linked list 排序並確保空間複雜度為 O(1)?」
  • 三月分回顧信件(4/1): 如何用 Bitwise 提高程式效率,了解前置處理器的原理
  • 四月分回顧信件(5/5): 面對問題的態度,從提出問題->給出假設->驗證假設->解釋原因,建構正確思考路線,用數據說話。另外,課堂中學習 Atomic 的操作,POSIX Threads 中 mutex locks、condition variables、semaphores 的使用場景。
  • 五月份回顧信件(6/17): 理解如何透過模擬線性回饋移位暫存器(Linear Feedback Shift Register, LFSR)生成亂數,用來生成初始的隨機矩陣,SIMD 利用暫存器的特性,一次處理多筆資料,Loop unrolling 及 Loop tiling 提升記憶體的存取效率,用於提升矩陣相乘的速度。

我都有依照每月的學習回顧信件,寄送回顧信件,並在當月或隔月寄送,我給自己 10 分。

自我評量 (1 ~ 10)

GEOMEAN = \((3\times8\times9\times8\times9\times10)^{1/6} = 7.333\)

方案 B: 1 + floor(GEOMEAN) = 1 + 7 = 8