跳转至

博客

Clang 如何支持 CUDA 程序

前言

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

WSL2 内部实现探究

背景

最近看到 Windows Subsystem for Linux September 2023 update 声称 WSL2 最新的预览版本支持让 Linux 和 Windows 一定程度上共享网络地址空间,就像 WSL1 那样:

  • IPv6 support
  • Connect to Windows servers from within Linux using the localhost address 127.0.0.1
  • Connect to WSL directly from your local area network (LAN)
  • Improved networking compatibility for VPNs
  • Multicast support

因此比较想知道这是怎么做到的,但目前我手上还没有预览版本的 windows,因此目前先研究 WSL2 已有的功能是如何实现的,未来再回来更新这一部分。

Linux 内核格式与启动协议

背景

之前在各种场合遇到过各种 Linux 内核的文件名或格式,例如:

  • vmlinux
  • vmlinuz
  • uImage
  • bzImage
  • uImage

即使是同样的文件名,格式可能也是不一样的,相应的启动协议也可能不一样。这篇博客尝试结合 Linux,各种 Bootloader(QEMU,EDK-II,U-Boot,OpenSBI)的代码来研究不同的 Linux 二进制格式以及启动协议。

Podman 和 Docker Rootless 实践

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

在 QEMU 中运行 OpenBMC

背景

最近想给某台机器配一个 BMC,于是调研 OpenBMC 发行版,但是还没有找到可以买到的合适的 BMC,因此先在虚拟机中进行尝试。

SPEC CPU 2006 性能测试

背景

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

记录一次 CentOS AArch64 7 到 8 的升级

背景

有一台 AArch64 机器安装了 CentOS 7,想要升级到 CentOS 8,这篇博客主要讲讲折腾的整个过程,而不是教程:如果真要说,就是不要升级 CentOS 大版本,直接重装吧。如果真的想折腾,可以看看下面的内容。

VFIO - Virtual Function I/O

背景

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

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

Montgomery 模乘

背景

在密码学中,经常会涉及到模乘操作:\(a * b \bmod N\)。朴素的实现方法是,先求出 \(a * b\),再对 N 进行除法,那么余数就是模乘的结果。

但由于此时的 \(a\) \(b\) \(N\) 三个数都很大,在计算机上需要用大整数来表示,而大整数的乘法和除法都是需要耗比较多的时间的。如果用 Schönhage–Strassen 算法,计算两个 \(n\) 位大整数的乘法需要的时间是 \(O(n \log(n) \log(\log(n)))\)

定义

Montgomery 模乘是一种提高模乘的性能的方法。具体地,Montgomery 模乘需要一个参数 \(R\) 满足 \(R\)\(N\) 互质,且 \(R > N\),那么 Montgomery 模乘实现的是如下计算:

\[ M(a, b) = a * b * R^{-1} \bmod N \]

写一个 bash zsh 和 fish 都能跑的脚本

背景

bash 和 zsh 都实现了 POSIX shell 标准,因此写脚本的时候,比较容易兼容这两种常见的 shell。但现在 fish 也很流行,而 fish 不符合 POSIX shell 标准,很多地方语法多不兼容,能否写一个脚本,可以用 bash,zsh 和 fish 跑?

# The following commands should work
bash test.sh
zsh test.sh
fish test.sh

把博客生成器从 Hugo 迁移到 Mkdocs

距离上一次 Jekyll 迁移到 Hugo 已经过去了四年,这次正好 mkdocs-material 发了新的 beta 版本,加入了对博客的支持,所以就当小白鼠,把博客迁移到了 Mkdocs + Mkdocs-Material。

这次迁移比较顺利,除了 tag 和 category 少了一些页面以外,原来的文章的链接都是正常的。为什么要迁移呢,主要是最近写各种文档,Mkdocs 用的比较多,但是 Mkdocs 的 Markdown 很多地方和 Hugo 不太一样,下面列一些最难以忍受的 Hugo 的问题:

  1. 数学公式:Hugo 的 \ 需要转义,导致很多地方写数学公式都很麻烦,然后因为我经常要在 Hugo 和 Mkdocs 之间复制 Markdown,此时就需要很多手动工作。
  2. 资源路径:Hugo 的资源路径默认都是绝对路径,要引用其他文章的话,要么用啰嗦的 relref,要么就写绝对路径,比较头疼。Mkdocs 就很好,自动检测,帮我计算出实际的地址。

迁移的时候有很多细节上的不同,不过基本靠 VSCode 的正则表达式替换解决了。

不过,Mkdocs 又出现了 Jekyll 的老问题,就是性能比较差。当然了,不一定是 Mkdocs 本身的问题,也可能是 Mkdocs-Material 加各种插件的问题,目前还有待观察。无论如何,Python 调起来总归是比 Ruby 要容易。希望不要在未来的某一天,由从 Mkdocs 迁移回 Hugo。

ECDSA

ECDSA 是一个基于椭圆曲线的签名算法,使用时需要确定一个椭圆曲线,以及它的 base point \(G\),且 \(G\) 的阶是素数 \(n\)。ECDSA 支持如下的操作:

  1. 生成签名
  2. 验证签名
  3. 从签名和明文推导出公钥

生成树协议

本文的内容已经整合到知识库中。

Spanning Tree Protocol

STP(Spanning Tree Protocol)可以在 802.1D-1998 第 8 章中找到。STP 协议工作在交换机上,需要根据交换机连接的拓扑,自动计算出一个生成树,并且把不在生成树上的边禁用,这样即使连接的拓扑有环路,禁用以后就没有环了。有了 STP 以后,连接交换机的时候就可以刻意连成环,从而提供冗余。

从 libvirtd 迁移到 Proxmox VE

背景

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

LoongArch 初尝试

背景

最近应龙芯要求把监控程序移植到了 LoongArch 32 Reduced 架构上,趁此机会体验了一下 LoongArch 相关的软件和系统。

Tar 文件格式

本文的内容已经整合到知识库中。

背景

最近在解压 tar.gz 文件的时候,发现如果用 unar 解压,就会出现文件名截断到 100 个字节的问题,而如果用 gnu tar 解压,文件名就是正常的,因此深入研究了一下 Tar 的文件格式。实际上,这是因为早期 tar 格式设计的时候,就设定了路径最长 100 字节的限制,后来的扩展解决了这个问题,但是 unar 没能正确地识别扩展,导致解压路径出错。

使用 Docker 部署 OpenLDAP

OpenLDAP 是一个开源的用户系统实现,主要支持 LDAP 协议,可以给其他系统提供用户认证。下面讨论了如何在 Docker 中部署 OpenLDAP。

链接器的工作原理

背景

最近和同学讨论一些比较复杂的链接问题,遇到一些比较复杂的情况,因此复习一遍链接器的工作原理,在这里总结工作原理和常见的问题。