跳转至

software

2025 年我是怎么使用 AI 的

前言

经常看我博客的读者应该能看出来,我研究的主要是计算机系统结构方向,特别是处理器的微架构,几乎没有涉及到 AI 的内容,我也确实不喜欢 AI 研究,仅关注但不参与。但今年,因为各种 AI 技术尤其是 LLM 的发展,我确实成为了很多 AI 技术的用户,可以说 2025 年是我正经大规模用 AI 的元年,所以在年末做一个简单的总结。

本博客近三个月来的访问数据观察

写在前面

这个博客自 2014 年更新至今,已走过近十一个年头,累计发布了四百多篇文章。出于好奇,我一直想了解哪些内容更受读者欢迎。五年前,我曾配置过 Google Analytics,但使用体验并不理想,于是转而自行部署了 rybbit 实例来收集访问数据。如今三个月过去,是时候与大家分享一些有趣的发现。

P.S. 如果你对数据收集有所顾虑,可以屏蔽对应的 analytics 脚本。

Linux 的性能分析(Perf)实现探究

背景

最近使用 Linux 的性能分析功能比较多,但是很少去探究背后的原理,例如硬件的 PMU 是怎么配置的,每个进程乃至每个线程级别的 PMU 是怎么采样的。这篇博客尝试探究这背后的原理。

SPEC CPU 2017 在其他指令集上的编译

SPEC CPU 2017 官方只附带了 arm/ppc/sparc/riscv/x86 指令集的预编译 tools,如果要在其他指令集上使用,就需要首先编译 tools,过程如下:

# https://gist.github.com/cyyself/4cee148ad11081dde7b938e3584b4536
wget -O config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'
wget -O config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
cp config.* /mnt/tools/src/expat-2.1.0/conftools/
cp config.* /mnt/tools/src/make-4.2.1/config/
cp config.* /mnt/tools/src/rxp-1.5.0/
cp config.* /mnt/tools/src/specinvoke/
cp config.* /mnt/tools/src/specsum/build-aux/
cp config.* /mnt/tools/src/tar-1.28/build-aux/
cp config.* /mnt/tools/src/xz-5.2.2/build-aux/
# fix glob impl
# https://github.com/GQBBBB/GQBBBB.github.io/issues/10
# http://git.savannah.gnu.org/cgit/make.git/patch/?id=48c8a116a914a325a0497721f5d8b58d5bba34d4
sed -i 's/_GNU_GLOB_INTERFACE_VERSION ==/_GNU_GLOB_INTERFACE_VERSION >=/' /mnt/tools/src/make-4.2.1/glob/glob.c
# fix missing test_driver.pl
# https://bugs.gentoo.org/613772
# http://git.savannah.gnu.org/cgit/make.git/commit/tests/run_make_tests.pl?id=d9d4e06084a4c7da480bd49a3487aadf6ba77b54
sed -i 's/require "test_driver.pl";/use FindBin;\nuse lib "$FindBin::Bin";\n\0/' /mnt/tools/src/make-4.2.1/tests/run_make_tests.pl
# fix wildcard test sigsegv
# https://lore.kernel.org/all/20200122223655.2569-1-sno@netbsd.org/T/
# http://git.savannah.gnu.org/cgit/make.git/commit/?id=193f1e81edd6b1b56b0eb0ff8aa4b41c7b4257b4
sed -i 's/gl->gl_stat = local_stat;/gl->gl_lstat = lstat;\n\0/' /mnt/tools/src/make-4.2.1/dir.c
# missing include ctype.h for isxdigit
sed -i 's/#include "xfreopen.h"/#include <ctype.h>\n\0/' /mnt/tools/src/specsum/src/md5sum.c
# fix gcc version detection
sed -i 's/1\*)/1.\*)/g' /mnt/tools/src/perl-5.24.0/Configure
# fix gettime test
sed -i 's/timegm(0,0,0,1,0,70)/timegm(0,0,0,1,0,1970)/g' /mnt/tools/src/TimeDate-2.30/t/getdate.t
# fix re.o generated instead of re.so
sed -i 's/main/int main/g' /mnt/tools/src/perl-5.24.0/hints/linux.sh
# GCC 15 default C23 fixes:
# 1. missing __alignof_is_defined && alignof macro
sed -i 's/#include <stdalign.h>/#define __alignof_is_defined 1\n#define alignof _Alignof\n\0/' /mnt/tools/src/specsum/tests/test-stdalign.c
# 2. hack stdbool.h detection
sed -i 's/#ifdef HAVE_STDBOOL_H/#if 1/' /mnt/tools/src/specinvoke/specinvoke.h
# 3. fix conflicting types for cleanup_os
sed -i 's/cleanup_os();/cleanup_os(specinvoke_state_t *si);/' /mnt/tools/src/specinvoke/specinvoke.h
# 4. fix char ** incompatible conversion to char*
sed -i 's/safesysrealloc(environ,/safesysrealloc((char*)environ,/' /mnt/tools/src/perl-5.24.0/util.c
sed -i 's/safesysfree(environ);/safesysfree((char*)environ);/' /mnt/tools/src/perl-5.24.0/perl.c
# 5. fix SDBM_FILE* incompatible conversion to char *
sed -i 's/safefree(db)/safefree((char*)db)/' /mnt/tools/src/perl-5.24.0/ext/SDBM_File/SDBM_File.xs
# 6. fix conflicting types for malloc/free
sed -i 's/extern Malloc_t malloc/extern void *malloc/' /mnt/tools/src/perl-5.24.0/ext/SDBM_File/sdbm.c
sed -i 's/extern Free_t free proto((Malloc_t))/extern void free proto((void *))/' /mnt/tools/src/perl-5.24.0/ext/SDBM_File/sdbm.c
# build tools
cd /mnt && echo 'y' | SKIPTOOLSINTRO=1 FORCE_UNSAFE_CONFIGURE=1 MAKEFLAGS=-j16 ./tools/src/buildtools

例如在 LoongArch 上编译 SPEC CPU 2017 的 Dockerfile,假设 SPEC CPU 2017 已经解压到 /mnt

RUN cd /mnt && tar xvf install_archives/tools-src.tar
RUN wget -O config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'
RUN wget -O config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
RUN cp config.* /mnt/tools/src/expat-2.1.0/conftools/
RUN cp config.* /mnt/tools/src/make-4.2.1/config/
RUN cp config.* /mnt/tools/src/rxp-1.5.0/
RUN cp config.* /mnt/tools/src/specinvoke/
RUN cp config.* /mnt/tools/src/specsum/build-aux/
RUN cp config.* /mnt/tools/src/tar-1.28/build-aux/
RUN cp config.* /mnt/tools/src/xz-5.2.2/build-aux/
# https://gist.github.com/cyyself/4cee148ad11081dde7b938e3584b4536
# fix glob impl
# https://github.com/GQBBBB/GQBBBB.github.io/issues/10
# http://git.savannah.gnu.org/cgit/make.git/patch/?id=48c8a116a914a325a0497721f5d8b58d5bba34d4
RUN sed -i 's/_GNU_GLOB_INTERFACE_VERSION ==/_GNU_GLOB_INTERFACE_VERSION >=/' /mnt/tools/src/make-4.2.1/glob/glob.c
# fix missing test_driver.pl
# https://bugs.gentoo.org/613772
# http://git.savannah.gnu.org/cgit/make.git/commit/tests/run_make_tests.pl?id=d9d4e06084a4c7da480bd49a3487aadf6ba77b54
RUN sed -i 's/require "test_driver.pl";/use FindBin;\nuse lib "$FindBin::Bin";\n\0/' /mnt/tools/src/make-4.2.1/tests/run_make_tests.pl
# fix wildcard test sigsegv
# https://lore.kernel.org/all/20200122223655.2569-1-sno@netbsd.org/T/
# http://git.savannah.gnu.org/cgit/make.git/commit/?id=193f1e81edd6b1b56b0eb0ff8aa4b41c7b4257b4
RUN sed -i 's/gl->gl_stat = local_stat;/gl->gl_lstat = lstat;\n\0/' /mnt/tools/src/make-4.2.1/dir.c
# missing include ctype.h for isxdigit
RUN sed -i 's/#include "xfreopen.h"/#include <ctype.h>\n\0/' /mnt/tools/src/specsum/src/md5sum.c
# fix gcc version detection
RUN sed -i 's/1\*)/1.\*)/g' /mnt/tools/src/perl-5.24.0/Configure
# fix gettime test
RUN sed -i 's/timegm(0,0,0,1,0,70)/timegm(0,0,0,1,0,1970)/g' /mnt/tools/src/TimeDate-2.30/t/getdate.t
# fix re.o generated instead of re.so
RUN sed -i 's/main/int main/g' /mnt/tools/src/perl-5.24.0/hints/linux.sh
# GCC 15 default C23 fixes:
# 1. missing __alignof_is_defined && alignof macro
RUN sed -i 's/#include <stdalign.h>/#define __alignof_is_defined 1\n#define alignof _Alignof\n\0/' /mnt/tools/src/specsum/tests/test-stdalign.c
# 2. hack stdbool.h detection
RUN sed -i 's/#ifdef HAVE_STDBOOL_H/#if 1/' /mnt/tools/src/specinvoke/specinvoke.h
# 3. fix conflicting types for cleanup_os
RUN sed -i 's/cleanup_os();/cleanup_os(specinvoke_state_t *si);/' /mnt/tools/src/specinvoke/specinvoke.h
# 4. fix char ** incompatible conversion to char*
RUN sed -i 's/safesysrealloc(environ,/safesysrealloc((char*)environ,/' /mnt/tools/src/perl-5.24.0/util.c
RUN sed -i 's/safesysfree(environ);/safesysfree((char*)environ);/' /mnt/tools/src/perl-5.24.0/perl.c
# 5. fix SDBM_FILE* incompatible conversion to char *
RUN sed -i 's/safefree(db)/safefree((char*)db)/' /mnt/tools/src/perl-5.24.0/ext/SDBM_File/SDBM_File.xs
# 6. fix conflicting types for malloc/free
RUN sed -i 's/extern Malloc_t malloc/extern void *malloc/' /mnt/tools/src/perl-5.24.0/ext/SDBM_File/sdbm.c
RUN sed -i 's/extern Free_t free proto((Malloc_t))/extern void free proto((void *))/' /mnt/tools/src/perl-5.24.0/ext/SDBM_File/sdbm.c
# build tools
RUN cd /mnt && echo 'y' | SKIPTOOLSINTRO=1 FORCE_UNSAFE_CONFIGURE=1 MAKEFLAGS=-j16 ./tools/src/buildtools
RUN mkdir -p /mnt/config
RUN cd /mnt && . ./shrc && packagetools linux-loong64
RUN /mnt/install.sh -f

参考官方文档:Building the SPEC CPU®2017 Toolset

开发一个链接器(4)

本文同步发布到本人的知乎

前言

这个系列的前三篇博客实现了一个简单的静态链接器,它可以输入若干个 ELF .o 文件,输出 ELF 可执行文件或者动态库。接下来,我们要进一步支持动态库,不仅可以生成动态库,还支持让动态库参与到静态链接当中。

开发一个链接器(3)

本文同步发布到本人的知乎

前言

这个系列的前两篇博客实现了一个简单的静态链接器,它可以输入若干个 ELF .o 文件,输出 ELF 可执行文件。接下来,我们进一步支持动态库:输入若干个 ELF .o 文件,输出 ELF 动态库。

开发一个链接器(2)

本文同步发布到本人的知乎

前言

这个系列的第一篇博客实现了一个最简单的静态链接器,它可以输入单个 ELF .o 文件,输出 ELF 可执行文件。接下来,我们需要把它升级到支持输入两个或者更多的 ELF .o 文件。

开发一个链接器(1)

本文同步发布到本人的知乎

前言

无论是在课程中还是实践中,都经常和链接器打交道。在这个过程中,大概了解了它的工作原理,对于常见的错误可以知道大概是怎么一回事,以及如何解决。但最近遇到一些涉及到链接器内部的问题,才发现自己对链接器的内部的了解还是比较匮乏的。因此想到自己开发一个链接器,在开发的过程中学习。

Chromium 构建与移植

背景

Google Chrome 也用了很长时间了,但是一直没有尝试过构建 Chromium,这次趁着往 LoongArch 移植 Chromium 的机会,学习了一下 Chromium 的构建。

反向代理的 Partial Transfer 问题

反向代理已经是无处不在,但是如果反向代理没有根据使用场景调优,或者出现了一些异常,可能会带来不好的用户体验,并且现象十分奇怪,例如访问某 GitLab 实例的时候,偶尔会出现页面加载不完整的情况。

这些问题困扰了我们很久,到最后才发现,原来问题在反向代理上。下面就来回顾一下事情的经过。

包管理器打包命令速查

随着 Linux 使用逐渐深入,开始尝试参与到一些发行版/包管理器的维护当中。在此记录一下打包相关命令,方便自己速查。

Clang 如何支持 CUDA 程序

前言

编译 CUDA 程序的主要工具是 NVIDIA 提供的闭源编译器 NVCC,但实际上,NVCC 是基于 LLVM 开发的(来源:NVIDIA CUDA Compiler),NVIDIA 也把 NVCC 其中一部分逻辑贡献给了 LLVM 上游,使得 Clang 也可以在 CUDA 的配合下编译 CUDA 程序。这篇博客尝试研究 Clang/LLVM 如何实现 CUDA 程序的编译,主要是 Clang 前端部分,后端部分,也就是从 LLVM IR 到 NVPTX 的这一步还没有进行深入的研究。

Podman 和 Docker Rootless 实践

最近在配置公用机器的环境,需求是很多用户需要使用 docker,但是众所周知,有 docker 权限就等于有了 root 权限,因此正好想尝试一下现在的 Rootless 容器化方案,例如 docket rootless 和 podman。

SPEC CPU 2006 性能测试

背景

最近在网上看到龙芯 3A6000 的 SPEC CPU 2006 性能评测数据,想着自己也可以在手上的一些平台上测一测,把测试的过程记录在本文。

VFIO - Virtual Function I/O

背景

VFIO 是 Linux 内核中的一个功能,目的是把 PCIe 设备暴露给用户态的程序,进而可以暴露给虚拟机内的系统,也就是常说的虚拟机 PCIe 直通。为了保证安全性,VFIO 还会配置好 IOMMU,保证用户态程序无法利用设备的 DMA 访问到其他地址空间的数据。

本文探讨 VFIO 暴露的用户态 API 以及如何在用户态中使用 VFIO 直接控制 PCIe 设备。

从 libvirtd 迁移到 Proxmox VE

背景

之前用 libvirtd + virt-manager 做 Linux 上的虚拟化,好处是比较轻量级,但是远程控制起来比较麻烦,要么通过 RDP 访问 virt-manager 的 UI,要么就用 cockpit 在网页里去配置虚拟机。此时就会比较怀念 VMware ESXi 的网页,但是 ESXi 装完以后,宿主机就很不自由了,很多东西没法自定义。最后就想到在 Debian 上装一个 Proxmox VE,希望得到一个比较好的中间态。