开发一个链接器(3)
前言
这个系列的前两篇博客实现了一个简单的静态链接器,它可以输入若干个 ELF .o 文件,输出 ELF 可执行文件。接下来,我们进一步支持动态库:输入若干个 ELF .o 文件,输出 ELF 动态库。
这个系列的前两篇博客实现了一个简单的静态链接器,它可以输入若干个 ELF .o 文件,输出 ELF 可执行文件。接下来,我们进一步支持动态库:输入若干个 ELF .o 文件,输出 ELF 动态库。
这个系列的第一篇博客实现了一个最简单的静态链接器,它可以输入单个 ELF .o 文件,输出 ELF 可执行文件。接下来,我们需要把它升级到支持输入两个或者更多的 ELF .o 文件。
无论是在课程中还是实践中,都经常和链接器打交道。在这个过程中,大概了解了它的工作原理,对于常见的错误可以知道大概是怎么一回事,以及如何解决。但最近遇到一些涉及到链接器内部的问题,才发现自己对链接器的内部的了解还是比较匮乏的。因此想到自己开发一个链接器,在开发的过程中学习。
Google Chrome 也用了很长时间了,但是一直没有尝试过构建 Chromium,这次趁着往 LoongArch 移植 Chromium 的机会,学习了一下 Chromium 的构建。
VIPT(Virtual Index Physical Tag)是 L1 数据缓存常用的技术,利用了虚拟地址和物理地址的 Index 相同的特性,得以优化 L1 数据缓存的读取。但是 VIPT 的使用,与页表大小和 L1 数据缓存大小都有关系。这篇博客探讨一下,VIPT 技术背后的一些问题。
反向代理已经是无处不在,但是如果反向代理没有根据使用场景调优,或者出现了一些异常,可能会带来不好的用户体验,并且现象十分奇怪,例如访问某 GitLab 实例的时候,偶尔会出现页面加载不完整的情况。
这些问题困扰了我们很久,到最后才发现,原来问题在反向代理上。下面就来回顾一下事情的经过。
mkdocs-material 支持 Instant Navigation:启用了以后,在网页里点击其他页面的时候,它会用类似 SPA 的方法,去 fetch 新的网页,然后原地替换,而不是让浏览器跳转过去,可以提升用户体验。
但是在用这个功能的时候,会发现其实并不是那么简单。。。
最近需要跑某个 x86 only 且需要 GUI 的程序,以往都是跑在远程 Linux/Windows 机器上再远程桌面去使用。最近看到了一些比较成熟的在 macOS 上跑 Linux 虚拟机 + Rosetta 的办法(M1 Mac で Vivado が動いた!),因此记录下来。
名称 | CPU 核心 | GPU 核心 | 神经网络引擎 | 内存带宽 | 内存大小 |
---|---|---|---|---|---|
M1 | 4+4 | 7/8 | 16 | 8GB/16GB | |
M1 Pro | 6+2/8+2 | 14/16 | 16 | 200GB/s | 16GB/32GB |
M1 Max | 8+2 | 24/32 | 16 | 400GB/s | 32GB/64GB |
M1 Ultra | 16+4 | 48/64 | 32 | 800GB/s | 64GB/128GB |
M2 | 4+4 | 8/10 | 16 | 100GB/s | 8GB/16GB/24GB |
M2 Pro | 6+4/8+4 | 16/19 | 16 | 200GB/s | 16GB/32GB |
M2 Max | 8+4 | 30/38 | 16 | 400GB/s | 32GB/64GB/96GB |
M2 Ultra | 16+8 | 60/76 | 32 | 800GB/s | 64GB/128GB/192GB |
M3 | 4+4 | 10 | 16 | 100GB/s | 8GB/16GB/24GB |
M3 Pro | 5+6/6+6 | 14/18 | 16 | 150GB/s | 18GB/36GB |
M3 Max | 10+4/12+4 | 30/40 | 16 | 300GB/s/400GB/s | 36GB/48GB/64GB/96GB/128GB |
来源:
编译 CUDA 程序的主要工具是 NVIDIA 提供的闭源编译器 NVCC,但实际上,NVCC 是基于 LLVM 开发的(来源:NVIDIA CUDA Compiler),NVIDIA 也把 NVCC 其中一部分逻辑贡献给了 LLVM 上游,使得 Clang 也可以在 CUDA 的配合下编译 CUDA 程序。这篇博客尝试研究 Clang/LLVM 如何实现 CUDA 程序的编译,主要是 Clang 前端部分,后端部分,也就是从 LLVM IR 到 NVPTX 的这一步还没有进行深入的研究。
最近看到 Windows Subsystem for Linux September 2023 update 声称 WSL2 最新的预览版本支持让 Linux 和 Windows 一定程度上共享网络地址空间,就像 WSL1 那样:
因此比较想知道这是怎么做到的,但目前我手上还没有预览版本的 windows,因此目前先研究 WSL2 已有的功能是如何实现的,未来再回来更新这一部分。
之前在各种场合遇到过各种 Linux 内核的文件名或格式,例如:
即使是同样的文件名,格式可能也是不一样的,相应的启动协议也可能不一样。这篇博客尝试结合 Linux,各种 Bootloader(QEMU,EDK-II,U-Boot,OpenSBI)的代码来研究不同的 Linux 二进制格式以及启动协议。
最近在配置公用机器的环境,需求是很多用户需要使用 docker,但是众所周知,有 docker 权限就等于有了 root 权限,因此正好想尝试一下现在的 Rootless 容器化方案,例如 docket rootless 和 podman。
有一台 AArch64 机器安装了 CentOS 7,想要升级到 CentOS 8,这篇博客主要讲讲折腾的整个过程,而不是教程:如果真要说,就是不要升级 CentOS 大版本,直接重装吧。如果真的想折腾,可以看看下面的内容。
VFIO 是 Linux 内核中的一个功能,目的是把 PCIe 设备暴露给用户态的程序,进而可以暴露给虚拟机内的系统,也就是常说的虚拟机 PCIe 直通。为了保证安全性,VFIO 还会配置好 IOMMU,保证用户态程序无法利用设备的 DMA 访问到其他地址空间的数据。
本文探讨 VFIO 暴露的用户态 API 以及如何在用户态中使用 VFIO 直接控制 PCIe 设备。
在密码学中,经常会涉及到模乘操作:\(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 模乘实现的是如下计算:
前段时间,@lwpie 发现一段 C++ 代码在 macOS 下,分别用自带的 Clang 编译和用 Homebrew 的 GCC 编译,性能差距接近一个数量级,下面是运行时间:
bash 和 zsh 都实现了 POSIX shell 标准,因此写脚本的时候,比较容易兼容这两种常见的 shell。但现在 fish 也很流行,而 fish 不符合 POSIX shell 标准,很多地方语法多不兼容,能否写一个脚本,可以用 bash,zsh 和 fish 跑?