Compare commits

..

No commits in common. "7e9c87de440536977358ba491dd97c3b61238a0c" and "fda4c01c226e14c33208cfabc7356616e9af9ea6" have entirely different histories.

271 changed files with 764 additions and 161 deletions

View File

@ -23,7 +23,7 @@ tags:
在前12年的学生生涯中我们都在期待着这一次的暑假以为在这个没有作业的假期里我们就可以充分的享受人间的美好。可是当时我们不知道这人间的烦恼可不止作业这一种无论是突如其来的疫情导致开学延期还是等待录取时的不安。
虽说在暑假时,拥有了自己的笔记本电脑,可是在高中三年屯下的游戏还是没有玩几个,看来我也是“喜加一”的受害者。虽然在高考后入坑了原神,但是假期间我并没有太过投入的玩。
暑假下定决心要好好的学一学可是看着我gitee上暑假期间那稀疏的提交我就知道我又摸了一个暑假的鱼。
![gitee贡献](./2021-final/1.webp)
![gitee贡献](./2021-final/1.png)
即使我想写的很多项目都没有被扎实的推进下来但是学习的一些的C语言还是让我受益匪浅。
现在看来,这个假期真是,**学也没有学好,耍也没有耍好**的典型。

BIN
YaeBlog/source/posts/2021-final/1.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -57,11 +57,11 @@ date: 2022-12-30 14:58:12
小小的总结一下2022年可以算得上是一事无成的一年还搞砸了不少的事情。在写代码上进展有限成绩上大幅倒退说好的六级英语和大学物理竞赛都没有参加在年末应对疫情进展的时候更是把“不知所措”这个成语诠释的淋漓尽致。
![](./2022-final/2022-12-30-14-26-19-QQ_Image_1672381538441.webp)
![](./2022-final/2022-12-30-14-26-19-QQ_Image_1672381538441.jpg)
关于今年的人际交往和社会关系我愿意用QQ2022年年终总结中的一张截屏来总结这张图片透漏出一种无可救药的悲伤。
![](./2022-final/2022-12-30-14-28-12-QQ_Image_1672381543836.webp)
![](./2022-final/2022-12-30-14-28-12-QQ_Image_1672381543836.jpg)
## 展望

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

View File

@ -32,7 +32,7 @@ date: 2022-08-22 15:39:13
- 下定决定要参加下一学期的物理竞赛,但是在听了讲座之后直接决定开学再开始学习,~~我知道我在家没法学习,俗称开摆~~
- 又捡起了`Blender`,并在[Github](https://github.com/tanjian1998/bupt_minecraft)上找到了伟大的前辈们在`Minecraft`里复刻的老校区,希望能用`Blender`渲染几张图当作桌面。
![唯一的一张成品](result1.webp)
![唯一的一张成品](result1.png)
> 在此感谢所有为此付出过汗水的前辈们,让我这个即将搬入老校区的萌新能提前一睹老校区的风采。

BIN
YaeBlog/source/posts/2022-summer-vacation/result1.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

View File

@ -44,7 +44,7 @@ date: 2024-2-29 20:18:19
2023年最令我吃惊的事情是我刷B站的时长
![image-20240303165826486](2023-final/image-20240303165826486.webp)
![image-20240303165826486](2023-final/image-20240303165826486.png)
容易计算得出我一共看了64天的B站接近六分之一的时间都在看。虽然我确实有着在干活的时候黑听B站和把B站当作音乐播放器的习惯但是这个时间未免有点太长了。下一年一定要在这个方面做出一定的改变将更多的时间放在看书上面去~~虽然写这句话的时候我就在黑听B站~~。

BIN
YaeBlog/source/posts/2023-final/image-20240303165826486.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -70,7 +70,7 @@ tags:
不过我的B站观看时长再度增长30%,这好吗,这不好,~~有这么多时间刷B站鬼知道你匆匆在哪了~~。
![image-20250115171809775](./2024-final/image-20250115171809775.webp)
![image-20250115171809775](./2024-final/image-20250115171809775.png)
### 未来

BIN
YaeBlog/source/posts/2024-final/image-20250115171809775.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

@ -44,7 +44,7 @@ date: 2022-07-27 11:34:49
而且采用 `Git`还有一个好处,采用 `Github``Insight`功能可以轻松的看出大家的贡献值()。
![img](1.webp)
![img](1.png)
## 一些技术上的收获

BIN
YaeBlog/source/posts/big-homework/1.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -131,7 +131,7 @@ Hexo init blog
```
Hexo会以blog为名称创建一个博客文件夹这个文件夹的内容为
![文件夹截图](1.webp)
![文件夹截图](1.png)
`node_modules`文件夹是Hexo需要用到的一些npm依赖包的存放地址`public`文件夹下是由Hexo渲染产生的静态博客文件`scaffolds`文件夹是博客用到的模板文件,在默认情况下应该有`draft.md`,`page.md`,`post.md`三个模板文件。`themes`是Hexo中可以使用的主题文件。主题也是Hexo一个非常方便的设计我们可以方便使用其他人编写的Hexo Themes让自己的博客在不同的风格之间变换。`source`文件夹就是存放我们写作的博客的地方。一般这里面会有两个子文件夹,`_draft`, `_posts`。我们在里面在创建一个`img`文件夹,把自己的头像图片和网站的图标文件都放在里面,在之后的设置的时候使用。
@ -146,7 +146,7 @@ INFO Hexo is running at http://localhost:4000/ . Press Ctrl+C to stop.
会在本地运行Hexo自带的一台静态博客服务器。我们用浏览器访问http://localhost:4000, 就可以看见Hexo博客的初始界面
![初始截图](2.webp)
![初始截图](2.png)
这便说明安装成功了,~~可以开香槟了~~

BIN
YaeBlog/source/posts/build-blog-record/1.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

BIN
YaeBlog/source/posts/build-blog-record/2.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

@ -7,7 +7,6 @@ tags:
---
我们编译是这样的,在本平台上编译只要敲三条命令就好了,而交叉编译要考虑的就很多了。
<!--more-->
@ -46,7 +45,7 @@ tags:
通常一份GNU工具链只能针对一个平台进行编译但是LLVM工具链是一套先天的交叉编译工具链例如对于`llc`工具,使用`llc --version`命令可以看见该编译器可以生成多种目标平台上的汇编代码:
![image-20240824120646587](./build-dotnet-from-source/image-20240824120646587.webp)
![image-20240824120646587](./build-dotnet-from-source/image-20240824120646587.png)
在使用`clang++`时加上`--target=<triple>`指定目标三元组就可以进行交叉编译。
@ -63,7 +62,7 @@ int main()
}
```
![image-20240824121425007](./build-dotnet-from-source/image-20240824121425007.webp)
![image-20240824121425007](./build-dotnet-from-source/image-20240824121425007.png)
看样子交叉编译也不是开箱即用的。最开始我们猜想系统提供的LLVM工具链没有被配置为交叉编译因此尝试在本地自行编译一套LLVM工具链。
@ -82,7 +81,7 @@ cmake ../llvm-project.src/llvm \
编译之后的成果会安装到`/usr/local/`目录下,而在`$PATH`环境变量中`/usr/local`位置将在`/usr`目录之前因此调用时将会优先调用我们自行编译的LLVM工具链而不是系统中安装的LLVM工具链。
![image-20240824134158262](./build-dotnet-from-source/image-20240824134158262.webp)
![image-20240824134158262](./build-dotnet-from-source/image-20240824134158262.png)
但是使用这套编译工具链仍然会爆出和之前一样的问题。说明这并不是系统安装LLVM工具链的问题。仔细一想也确实这里提示找不到对应的头文件应该是找不到RISC-V架构之下的头文件——这里的也是交叉编译的主要问题所在虽然LLVM工具链宣称自己是原生支持交叉编译的但是没人宣称说标准库和头文件是原生的。这里我们就需要一个根文件系统来提供这些头文件和各种库文件。
@ -199,7 +198,7 @@ clang++ --target=riscv64-linux-gnu --sysroot=$ROOTFS_DIR -fuse-ld=lld hello.cpp
第一个问题的回答是Arch Linux安装的LLVM工具是可以交叉编译的。虽然在Arch Linux官方构建LLVM工具链的[构建脚本](https://gitlab.archlinux.org/archlinux/packaging/packages/clang/-/blob/main/PKGBUILD?ref_type=heads)中没有使用`LLVM_TARGETS_TO_BUILD`参数,但是这个参数的默认值是`all`。这一点我们也可以通过实验来验证。
![image-20240824153514149](./build-dotnet-from-source/image-20240824153514149.webp)于是回到编译`llvm`的目录下执行`cat install_manifest.txt | sudo xargs rm`。
![image-20240824153514149](./build-dotnet-from-source/image-20240824153514149.png)于是回到编译`llvm`的目录下执行`cat install_manifest.txt | sudo xargs rm`。
第二个问题的回答可以使用实验来验证,首先安装`riscv64-linux-gnu-gcc`,然后将根文件系统的位置设置为`/usr/riscv64-linux-gnu`,重新编译上面的你好世界样例。编译之后可以正常执行。
@ -230,4 +229,4 @@ export ROOTFS_DIR=<rootfs>
但是现在的.NET在RISC-V平台上还是废物一个甚至连`dotnet new`都跑不过,下一步看看能不能运行一下运行时的测试集看看。
![image-20240824214145759](./build-dotnet-from-source/image-20240824214145759.webp)
![image-20240824214145759](./build-dotnet-from-source/image-20240824214145759.png)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

View File

@ -17,7 +17,7 @@ date: 2022-05-08 11:35:19
我项目的结构大致如图所示:
![](1.webp)
![](1.png)
在`include`的头文件目录下有两个头文件,`rail.h`和`bus.h`,这两个头文件分别定义了两个结构体`rail_node_t`和`bus_t`。
@ -68,7 +68,7 @@ typedef struct bus bus_t;
项目的`test`文件夹下是单元测试文件夹,但是在编译的时候会报错
![](2.webp)
![](2.png)
大意就是在一个google test内部的头文件中有几个函数找不到定义这个函数都位于`io.h`这个头文件中。

BIN
YaeBlog/source/posts/c-include-problems/1.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

BIN
YaeBlog/source/posts/c-include-problems/2.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

View File

@ -5,14 +5,13 @@ tags:
- 杂谈
---
2024年的中国计算机大会于10月24日到10月26日在浙江省金华市东阳市横店镇举办而鄙人在下不才我有幸受到实验室资助前去参观学习。
<!--more-->
首先开幕式镇楼。
![image-20241102212738598](./cncc-2024/image-20241102212738598.webp)
![image-20241102212738598](./cncc-2024/image-20241102212738598.png)
## 学术上
@ -22,11 +21,11 @@ tags:
第一个报告是华为庞加莱实验室秦彬娟老师的《异构智算时代的操作系统演进》。报告高屋建瓴从比较宏观的角度上介绍了当前异构融合操作系统诞生的背景、发展的方向。在报告中重点介绍了一种异构融合操作系统的设计思路通过三层架构基于互联池化技术构建AI时代的融合算力系统。系统中的三层包括1池化基础底层包括多设备的融合和池化设备虚拟化2异构融合核心子系统例如异构融合调度系统、异构融合内存和异构融合存储系统3异构核心服务。总的来说这个报告在一定程度上勾勒出了未来一个异构融合操作系统应有的各项功能但是显然这一操作系统的实现还存在着明显的困难。
![image-20241102211959206](./cncc-2024/image-20241102211959206.webp)
![image-20241102211959206](./cncc-2024/image-20241102211959206.png)
下面一个报告是较为有干货的报告北京航空航天大学刘瀚骋老师的《异构融合OS及多样性内存管理框架》。报告中介绍了一个称作`FMMU`的系统是对于异构融合操作系统中内存管理系统的探索。报告中首先介绍了内存池化技术对于异构融合操作系统的重要性指出分布式共享内存Distributed Shared Memory可能是实现内存池化技术的未来。然后介绍了将部分内存管理中的计算卸载到可编程网络硬件中来加速分布式内存访问的新思路。最后在报告中提到了内存管理技术如何解决错误预测和错误回复的问题。虽然在听的时候没太注意但是现在总结的时候才发现这个报告的思路似乎有点混乱尤其是最后一点和内存管理系统并没有什么直接的关系而且这个内存管理系统似乎不是**异构系统**的内存管理,反而是分布式系统的内存管理。不过总的来说,这个报告还是非常实际的,介绍了不少当前异构融合操作系统中的内存管理面临的问题和解决问题的探索。
![image-20241102212355390](./cncc-2024/image-20241102212355390.webp)
![image-20241102212355390](./cncc-2024/image-20241102212355390.png)
第三个报告是国防科技大学李东升老师的《异构计算环境下的分布式深度学习训练》。报告首先从李老师的主业——并行计算起手,介绍了深度学习训练过程中主要的各种并行方法,例如数据并行、模型并行和混合并行等,指出目前大模型的并行训练存在着计算/存储/通信难的问题。因此提出了一个智能模型训练并行任务划分方法1基于符号算子的计算图定义方法2面向Transformer模型的流水线并行任务划分方法3异构资源感知的流水线并行任务划分方法。然后针对分布式模型训练中通信调度存在的通信墙、数据依赖关系复杂等的问题提出综合词嵌入表的稀疏通信调度技术、流水线并行的P2P通信调度技术、模型计算的统一操作执行引擎和网络链路感知的通信执行引擎的通信调度技术。最后提到了智能模型训练 的内存优化技术针对现有重计算技术re-computing和存储交换swapping技术存在的问题提出了一种面向大型智能模型训练的细粒度内存优化方法`DELTA`。
@ -50,7 +49,7 @@ Plane讨论没有参加。
第二个报告是南京大学冯新宇老师的《基于仓颉语言的嵌入式DSL开发》同时冯新宇老师也是仓颉语言的首席架构师。冯老师的这个报告主要聚焦于仓颉语言提供的嵌入式DSL能力而嵌入式DSL这一设计范式已经在前端开发中展现了不俗的潜力。报告中介绍了嵌入式DSL出现的背景仓颉中为了提供嵌入式DSL而引入的语法糖、仓颉提供的嵌入式DSL工具箱等。虽然仓颉语言是一个主要面向上层应用开发的语言但是仓颉中丰富的DSL能力还是给异构编程模型的设计提供了不少的启发。而且目前在各种深度学习编译器中DSL的应用也非常广泛例如`triton`。
![image-20241102212536635](./cncc-2024/image-20241102212536635.webp)
![image-20241102212536635](./cncc-2024/image-20241102212536635.png)
第三个报告是在存算一体的芯片上做数据库的加速第四个报告是OpenHarmony上`ArkTS`程序的静态分析,都没怎么听。

BIN
YaeBlog/source/posts/cncc-2024/image-20241102211959206.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

BIN
YaeBlog/source/posts/cncc-2024/image-20241102212355390.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

BIN
YaeBlog/source/posts/cncc-2024/image-20241102212536635.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

BIN
YaeBlog/source/posts/cncc-2024/image-20241102212738598.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 639 KiB

View File

@ -198,7 +198,7 @@ bazel build -c opt --strip=ALWAYS \
如果在编译的过程中提示缺失`dx.jar`这个文件而且你用的SDK版本还是高于31的那可能是SDK中缺失了这个文件可以将SDk降级到30就含有这个文件了。我使用的解决办法比较离奇我是将30版本的SDK文件中的这个文件软链接过来解决了这个问题。
![](compile-mediapipe/2023-01-15-22-05-41-Screenshot_20230115_220521.webp)
![](compile-mediapipe/2023-01-15-22-05-41-Screenshot_20230115_220521.png)
编译消耗的时间可能比较的长,耐心等待即可。
@ -227,7 +227,7 @@ bazel build -c opt //mediapipe/graphs/pose_tracking:pose_tracking_gpu_binary_gra
然后还需要从服务器上下载`tflite`文件,`Pose Tracking`这个解决方案需要两个`tflite`文件,第一个是[pose_detection.tflite](https://storage.googleapis.com/mediapipe-assets/pose_detection.tflite),第二个文件则有三个不同的选择,分别对于解决方案中提供的三个质量版本:
![](compile-mediapipe/2023-01-19-20-20-40-Screenshot_20230119_202008.webp)
![](compile-mediapipe/2023-01-19-20-20-40-Screenshot_20230119_202008.png)
下载地址是[pose_landmark_full.tflite](https://storage.googleapis.com/mediapipe-assets/pose_landmark_full.tflite)[pose_landmark_heavy.tflite](https://storage.googleapis.com/mediapipe-assets/pose_landmark_heavy.tflite)和[pose_landmark_lite.tflite](https://storage.googleapis.com/mediapipe-assets/pose_landmark_lite.tflite)。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -1,21 +1,20 @@
---
title: 计算机系统结构——流水线复习
date: 2024-06-12T20:27:25.0000000
tags:
- 计算机系统结构
- 学习资料
- 计算机系统结构
- 学习资料
date: 2024-06-12 20:27:25
---
让指令的各个执行阶段依次进行运行是一个简单而自然的想法,但是这种方式执行速度慢、运行效率低。因此一个很自然的想法就是将指令重叠起来运行,让执行功能部件被充分的利用起来,这就是**流水线**。
流水线的表示方法有两种。
![image-20240612184855300](computer-architecture-pipeline/image-20240612184855300.webp)
![image-20240612184855300](computer-architecture-pipeline/image-20240612184855300.png)
第一种被称作**连接图**,清晰的表达出了流水线内部的逻辑关系。
![image-20240612184949777](computer-architecture-pipeline/image-20240612184949777.webp)
![image-20240612184949777](computer-architecture-pipeline/image-20240612184949777.png)
> 上图中给出了两个流水线中的概念:通过时间和排空时间。其中通过时间又被称作装入时间,是指第一个任务进入流水线到完成的事件;排空时间则相反,是最后一个任务通过流水线的时间。
@ -41,7 +40,7 @@ tags:
- 静态流水线,同一时间内,多功能流水线的各段只能按照同一种功能的方式连接。
- 动态流水线,同一时间内,多功能流水线的各种可以按照不同的方式连接,执行不同的功能。
![image-20240612190426368](computer-architecture-pipeline/image-20240612190426368.webp)
![image-20240612190426368](computer-architecture-pipeline/image-20240612190426368.png)
按照流水线中是否存在反馈回路分类:
@ -59,7 +58,7 @@ tags:
- 加速比,同一任务,不使用流水线所使用时间与使用流水线所用时间比。
- 效率,流水线设备的利用率。
![image-20240612192700169](computer-architecture-pipeline/image-20240612192700169.webp)
![image-20240612192700169](computer-architecture-pipeline/image-20240612192700169.png)
在设计流水线的过程中存在若干问题。
@ -69,7 +68,7 @@ tags:
一个典型的五段流水线MIPS流水线
![image-20240612193301372](computer-architecture-pipeline/image-20240612193301372.webp)
![image-20240612193301372](computer-architecture-pipeline/image-20240612193301372.png)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

View File

@ -92,7 +92,7 @@ sudo systemctl enable sddm.service
我目前实现的效果大概长这样:
![](2023-01-12-13-28-38-Screenshot_20230112_132829.webp)
![](2023-01-12-13-28-38-Screenshot_20230112_132829.png)
颇有一种`Windows`和`MacOS`杂交的风格。
@ -106,7 +106,7 @@ sudo systemctl enable sddm.service
先上一张`shell`的系统概览截图:
![](2023-01-12-13-36-45-Screenshot_20230112_133628.webp)
![](2023-01-12-13-36-45-Screenshot_20230112_133628.png)
终端模拟器直接使用的`konsole`,目前没有进行改动。

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@ -18,7 +18,7 @@ typora-root-url: daily-linux-2
最近恰好被平铺式的窗口管理器种草又在B站上看见一个动画绚丽的`wayland`合成器——[Hyprland](https://hyprland.org/),当即脑袋一热,就把`kde`干掉,装上了`hyprland`。
![img](df4211f6be2724b3b4725f7ce5a4078818844857.avif)
![img](df4211f6be2724b3b4725f7ce5a4078818844857.jpg)
安装`hyprland`的过程非常舒适,`hyprland`被打包为一个单独的二进制文件,使用`pacman`安装之后直接在`tty`下执行:
@ -46,7 +46,7 @@ Hyprland
各种在学习过程中遇到的工具软件基本上都工作运行良好。当然因为没有设置缩放的问题而导致字体都很小。因为如果在配置文件中设置缩放之后会导致字体发虚。下面的截图就是我将我的2K显示屏设置为150%缩放的效果,~~虽然在截图中的效果不明显~~。目前在常用软件中唯一让我十分不满意的软件是`wps`,使用体验完全无法和`offices`相提并论,目前我正在研究使用`wine`运行`offices`,如果成功了就再水一篇博客庆祝一下。
![image-20230702205919301](image-20230702205919301.webp)
![image-20230702205919301](image-20230702205919301.png)
> 最新的进展是使用`wine`没法安装学校提供的`office 2021`,同时我又不愿意使用古老的`office`版本,但是我发现一个称作`onlyoffice`的第三方软件蛮好用的,等我试用一段时间再说。
>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

View File

@ -53,7 +53,7 @@ date: 2023-09-04 14:47:46
- `Meta+F`全屏应用
- `Meta+W`关闭应用
![](Screenshot_20230904_144149.webp)
![](Screenshot_20230904_144149.png)
### Fuck You NVIDIA

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

View File

@ -1,12 +1,11 @@
---
title: 日用Linux挑战 第4篇 新的开始
date: 2024-03-09T14:00:00.0000000
tags:
- Linux
- 杂谈
- Linux
- 杂谈
date: 2024/03/09 14:00:00
---
小步快跑,面向未来。
<!--more-->
@ -19,7 +18,7 @@ tags:
相较于古老但是稳定的`Ext4`文件系统,`Btrfs`对我来说最大的好处便是可以零成本的创建快照,便于在出现错误的时候及时回滚或者直接重装系统。因此,为了方便快照的生成和回滚,我在安装系统时使用**扁平化**的子分区划分方法:即尽力避免出现嵌套的子分区,所有需要快照的分区都处在`/`目录之下:
![Screenshot_20240309_115143](daily-linux-4/Screenshot_20240309_115143.webp)
![Screenshot_20240309_115143](daily-linux-4/Screenshot_20240309_115143.png)
- `@`为根分区,挂载在`/`目录之下,打开写时复制;
- `@home`为家目录分区,挂载在`/home`目录之下,打开写时复制;
@ -45,7 +44,7 @@ sudo btrfs send /.snapshots/home@20240225 | zstd | ssh root@remote "zstd -d | bt
算起来,我已经和`Wayland`显示协议相爱相杀了整整一年了,从`KDE plasma X`到`Hyprland`,再尝试小众的`labwc`,最后回到了`KDE plasma X`。而在2024年2月29日`KDE plasma`释出6.0版本,将`Wayland`作为默认的显示协议,我也在第一时间更新了版本并使用`wayland`显示协议。现在,我可以比较确定的说,`Wayland`目前已经达到可用的水平了,而且我还是使用`RTX 3060`显卡。
![image-20240309130329784](daily-linux-4/image-20240309130329784.webp)
![image-20240309130329784](daily-linux-4/image-20240309130329784.png)
不过相较于`AMDGPU`可以开箱即用,使用`NVIDIA`启动需要配置如下的模块参数:
@ -65,7 +64,7 @@ options nvidia_drm modeset=1 fbdev=1
不过`XWayland`应用程序在使用`NVIDIA`驱动时会存在一个神奇的**同步失败**问题,表现为在`xwayland`中部分控件闪烁,交替显示更新前和更新后的帧,而且这个问题几乎不能被截屏抓到,具体可以见`freedesktop`上的这个[issue](https://gitlab.freedesktop.org/xorg/xserver/-/issues/1317)。虽然这个议题下面有着很长的讨论,还是建议大家完整的看一遍,里面甚至还有:
![image-20240309131750535](daily-linux-4/image-20240309131750535.webp)
![image-20240309131750535](daily-linux-4/image-20240309131750535.png)
省流:这个议题讨论了在`xserver`中提供显式同步的协议原语,方便图形驱动程序知道什么时候渲染的帧发生了变化。因此这并不是一个`NVIDIA`驱动程序的问题,而是需要将`Linux`显示协议栈从隐式同步迁移到显式同步。但是相关的工作还在开发过程中,因此解决方法有两个:
@ -78,9 +77,9 @@ options nvidia_drm modeset=1 fbdev=1
于是,我就在`Arch Wiki`上学到一条新知识:
![image-20240309134847166](daily-linux-4/image-20240309134847166.webp)
![image-20240309134847166](daily-linux-4/image-20240309134847166.png)
原来`efi`分区其实只用放`grub`
![img](daily-linux-4/cfd17cff0701a8e8c69fecf247f17fc1-1709963611271-2.webp)
![img](daily-linux-4/cfd17cff0701a8e8c69fecf247f17fc1-1709963611271-2.jpg)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -7,7 +7,6 @@ tags:
- 编译原理
---
JIT编译就一定比AOT编译慢吗
<!--more-->
@ -105,7 +104,7 @@ class Program
首先是为了更好发挥动态PGO的性能JIT编译器中为分层编译引入了更多的编译层数。需要引入更多编译层数的原因主要有两点。第一插入各种采样的指令和代码是需要代价的考虑到第0层编译的主要目标是为了降低编译的时间提高应用的启动速度在第0层编译过程中就不能插入太多的采样指令。因此编译器首先增加了一个新的编译层——采样第0层来解决这个问题。大部分的方法将在第一次运行时编译到缺少优化、缺少采样指令的第0层在运行时发现该方法被调用了多次之后JIT编译器将这个方法重新编译到采样第0层再经过一系列的调用之后JIT编译器将利用采样得到的信息对该方法重新进行编译并优化。第二在原始编译器模型中使用即时运行R2R方法编译的代码不能参加到动态PGO中尤其是考虑到几乎所有应用程序都会调用的核心库代码是采用R2R的方式进行运行的如果这部分的代码不能参加动态PGO将不能够完全发挥动态PGO的效果虽然核心库在提前编译的过程中会使用静态PGO进行一部分的优化。因此JIT编译器为R2R编译好的代码增加了一个新的编译器在运行时发现这部分代码被调用多次之后将会被JIT编译器编译到含有优化和采样代码的采样第1层随着调用次数的增加这部分的代码将可以利用采样得到的信息进行优化。下面这张图展现了不同编译方法在运行过程中可能达到的编译层级。
![image-20240828135354598](./dotnet-performance-8/image-20240828135354598.webp)
![image-20240828135354598](./dotnet-performance-8/image-20240828135354598.png)
JIT编译器也在第0层编译的过程中引入了更多的优化。虽然第0层编译的目的是缩短编译的时间但是许多的优化可以通过减少需要生成的代码数量来达到这个目的。常量折叠Constant Folding就是一个很好的例子。虽然这会让JIT编译器在第0层编译时花费更多的时间同运行时中的虚拟机交互来解析各种变量的类型但是这可以大量的减少JIT编译器需要生成的代码量尤其是对于下面这种涉及到类型判断的例子。
@ -214,7 +213,7 @@ void Run(string name, Action<int> body)
| -------- | ------------- | ------------- | ------------ |
| 原子指令 | 2,000,000,000 | 2,000,000,000 | 22241.9848ms |
| 朴素 | 2,000,000,000 | 220,525,235 | 277.3435ms |
| 随机 | 2,000,000,000 | 2,024,,587,268 | 527.5323ms |
| 随机 | 2,000,000,000 | 2,024,587,268 | 527.5323ms |
从数据上就可以发现,新方法可以在和朴素方法接近的运行时间下获得和使用原子指令接近的实际数值,而且运行时间会随着数值的增加进一步的减少,逐渐逼近朴素方法的运行时间。
@ -258,7 +257,7 @@ for (int trial = 0; trial < 5; trial++)
程序的输出是5次次采样统计的结果
![image-20240828155556375](./dotnet-performance-8/image-20240828155556375.webp)
![image-20240828155556375](./dotnet-performance-8/image-20240828155556375.png)
需要指出的是,虽然在上面的代码中使用和运行时代码中一样的“蓄水池”大小,但是在运行时并没有提前获得所有需要统计的数据,调用的统计数据是由多个不同的运行线程同时写入蓄水池中的。从结果中可以看出,虽然数值上并不准确,但是该算法准确的统计出了各个字符的出现趋势。
@ -457,4 +456,170 @@ static int ConditionalSelect(bool condition, int whenTrue, int whenFalse) =>
.NET提供的一种特性就是运行时安全这其中重要的一点就是对于数组、字符串和切片在运行时进行边界检查。但是这些边界检查就会在实际生成的代码中生成大量的分支判断这会导致程序运行的效率严重下降。因此如何让编译器在能够保证访问安全的情况下消除掉部分不必要的边界检查是编译器优化中的一个重要课题。
例如在一个常用数据结构——哈希表中,通常的实现是计算键的哈希值,并利用该哈希值作为下标在数组中获得存储的对象。考虑到哈希值是一个
例如在一个常用数据结构——哈希表中,通常的实现是计算键的哈希值,并利用该哈希值作为下标在数组中获得存储的对象。考虑到哈希值是一个`int`类型的变量但是哈希表中很少需要存储高达21亿对象因此往往需要对哈希值取模之后再作为数组的下标此时取模的值常常就是数组的长度。也就是说在这种情况下对于数组的访问是不可能出现越界的情况下。因此编译器可以为类似与如下的代码取消访问数组时的边界检查
```csharp
public class Tests
{
private readonly int[] _array = new int[7];
public int GetBucket() => GetBucket(_array, 42);
private static int GetBucket(int[] buckets, int hashcode) =>
buckets[(uint)hashcode % buckets.Length];
}
```
同样的,对于下面这些代码,编译器也可以取消访问数组时的边界检查:
```csharp
public class Tests
{
private readonly string _s = "\"Hello, World!\"";
public bool IsQuoted() => IsQuoted(_s);
private static bool IsQuoted(string s) =>
s.Length >= 2 && s[0] == '"' && s[^1] == '"';
}
```
### 常量折叠
常量折叠Constant Folding同样是一个编译器在生成代码时可以进行的重要优化这让编译器在计算在编译器时就可以确定的值而不是让他们留到运行时进行。最朴素的常量折叠——例如计算一个数学表达式的值——在这里不在赘述。在上面介绍函数内联时也涉及到了常量折叠的内容分层编译的引入也会使得常量折叠的应用范围变广这些都不在这里重复。
进行常量折叠优化时一个重要的问题是“教会”编译器哪些变量是常量。这方面编译器得到的提升有:
- 可以将一个字面值字符串的长度视为一个常数;
- 在进行空安全的检查时字面值字符串是必定不为空的;
- 编译器在编译时除了可以进行一些简单的数学运算,现在整个`System.Math`命名空间中提供的算法都可以在编译时进行运算;
- `static readonly`类型的字符串和数组长度被视为一个常数;
- `obj.GetType()`现在在JIT编译器明确了解类型的情况下可以被替换为一个常量
- `DateTime`等时间类型初始化时可以在编译期计算内存存储的时间。例如对于`new DateTime(2023, 9, 1)`将会直接被编译到`new DateTime(0x8DBAA7E629B4000)`。
上述这些并不能完全覆盖在.NET 6到.NET 8三个大版本之中引入的所有JIT编译器优化但是从中也可以一窥编译器优化的精巧之处。首先编译器的优化并不是一个个独立优化策略的组合而且各种优化策略的有机组合。方法的内联就是一个典型例子通过将被调用方法的内容暴露给调用者或者反过来让其他的各种优化策略发挥更大的作用。其次JIT编译器在编译优化方面可以发挥更伟大的作用。通过在程序运行时对于运行环境和程序本身有着更加深刻的理解JIT编译器可以在运行时发挥出更高的性能。
## 内存管理
.NET中的垃圾回收器GC负责管理应用程序的内存分配和释放。每当有对象新建时运行时都会将从托管堆为对象分配内存主要托管堆中还有地址空间运行时就会从托管堆为对象分配内存。不过内存并不是无限的垃圾回收器就负责执行垃圾回收来释放一些内存。垃圾回收器的优化引擎会根据所执行的分配来确定执行收回的最佳时机。
.NET中内存管理中的一个显著变更为将内存的抽象从段Segment修改为区域Region。段和区域之前最明显的区别是大小段是较大的内存——在64位的机器上一个段的大小万网是1GB、2GB或者是4GB而区域是非常小的单元在默认情况下只有4MB的大小。从宏观上来说之前的GC是为每个代的堆维持一个GB级别的内存范围而现在GC则是维持了许多个较小的内存区域这些内存区域可以被分配给各个代的堆或者其他可能涉及的堆使用。
垃圾回收器中还有两个引人注意的特性增加。第一个是动态的代提升和下降Dynamic Promotion and Demotion`DPAD`第二个是动态适应应用程序大小Dynamic Adaptive To Application Size`DATAS`)。`DPAD`特性允许GC在工作的过程中动态的设置一个区域的代数例如直接将一个可能存活时间非常长的对象配置为第2代而这在之前的GC模型中需要通过两次垃圾回收才能实现。而第二个特性`DATAS`旨在适应应用程序的内存要求即应用程序堆的大小和长期数据大小大致成正比即使在不同规格的计算机上执行相同的工作时运行时中堆的大小也是类似的。相比如下传统的服务器模式下的GC旨在提高程序的吞吐量允许内存的分配量基于吞吐量而不是应用程序的大小。`DATAS`对于各种突发类型的工作负载是非常有利的,同时通过允许堆大小按照工作负载的要求进行调整,这将让一些内存首先的环境直接受益。
### 无垃圾回收的堆
在程序中大量会涉及到使用常量字符串的情形,例如下面这个例子:
```csharp
public class Tests
{
public string GetPrefix() => "https://";
}
```
在.NET 7平台上这个方法会被JIT编译器编译之后得到下面这段本机代码
```assembly
; Tests.GetPrefix()
mov rax,126A7C01498
mov rax,[rax]
ret
; Total bytes of code 14
```
在这段代码中使用了两个`mov`指令,其中第一个指令加载存储这个字符串对象地址的地址,第二个读取该地址。从这段本机代码可以看见,尽管已经是在处理一个常量的字符串,但是编译器和运行时仍然需要为这个字符串在堆上分配一个`string`对象因为一个在堆上分配的对象在GC的控制下会在内存中发生移动编译器就不能为这个对象使用一个固定的内存地址需用从一个指定的地址读取该对象所在的地址。如果能让这个常量字符串分配在不会移动的内存区域中就能从编译器和GC两个方面上提高程序运行的效率。
为了优化这种生成周期和程序一致对象的内存管理,.NET 8中引入了一个新的堆——没有内存管理的堆。JIT编译器将会保证这些常量类型的对象将会被分配在这个堆中这种没有GC管理的堆也意味着JIT编译器可以为这些对象使用一个固定的内存地址在使用时避免掉了一次内存读取。
![Heaps where .NET Objects Live](./dotnet-performance-8/HeapsWhereNetObjectsLive.png)
将上述提高的示例代码使用.NET 8版本进行编译得到的代码如下从中也可以看出JIT编译器生成的代码只有一条`mov`指令,避免了一次内存访问。
```assembly
; Tests.GetPrefix()
mov rax,227814EAEA8
ret
; Total bytes of code 11
```
这个没有内存管理的堆引入还可以让其他的类型受益。例如对于`typeof(T)`返回的类型对象,容易想到一个程序集中所有类型对象的生命周期应该是和程序一致的,因此也可以在这个堆上分配所有这些类型对象。`Array.Empty<T>`也可以利用类似的思路分配在这个堆上。
### 值类型
因为可以避免在堆上分配内存,值类型已经在.NET的高性能代码中得到了广泛的应用虽然频繁的内存拷贝可能带来额外的性能开销。因此编译器对于值类型的各种优化就显得至关重要。
这部分优化中一个引人注目的点是值类型的“推广”promotion这里的推广意味着将一个结果划分为组成它的各种字段来区别对待。可以利用下面这个示例代码进行理解
```csharp
public class Tests
{
private ParsedStat _stat;
[Benchmark]
public ulong GetTime()
{
ParsedStat stat = _stat;
return stat.utime + stat.stime;
}
internal struct ParsedStat
{
internal int pid;
internal string comm;
internal char state;
internal int ppid;
internal int session;
internal ulong utime;
internal ulong stime;
internal long nice;
internal ulong starttime;
internal ulong vsize;
internal long rss;
internal ulong rsslim;
}
}
```
在这段代码中有一个较大的结构类型其的大小是80个字节。在没有启用推广的条件下进行运行`GetTime`方法编译得到的本机代码如下所示。在汇编代码中将下载栈上分配一片88字节的空间再将整个结构体直接复制到当前方法的栈上在复制完成之后计算两个字段的和并返回。
```assembly
; Tests.GetTime()
push rdi
push rsi
sub rsp,58
lea rsi,[rcx+8]
lea rdi,[rsp+8]
mov ecx,0A
rep movsq
mov rax,[rsp+10]
add rax,[rsp+18]
add rsp,58
pop rsi
pop rdi
ret
; Total bytes of code 40
```
而在打开推广的情况下运行得到的本机代码如下所示:
```assembly
; Tests.GetTime()
add rcx,8
mov rax,[rcx+8]
mov rcx,[rcx+10]
add rax,rcx
ret
; Total bytes of code 16
```
在这段汇编代码中JIT编译器只复制了两个需要使用的字段到当前方法的栈上这就大幅减少了值类型在方法调用之前产生内存复制开销。
## 还有更多……
行文至此,本篇已经字数超过一万字了,毫无疑问这将成为博客历史上最长的一篇文章。在这点字数中我们还只是**简略**的介绍了一下.NET平台过去的几个版本中涉及到的优化还主要聚焦于JIT编译器和内存管理的部分在这两个部分之后还有一个线程管理部分也是影响性能的关键组件同时.NET还提供了一个由数千个API组成的运行库这些类型中无论是基元类型还是泛型集合类型都获得了若干提升这些部分共同组成了这几个版本的性能奇迹。
本篇文章中的主要内容来自于.NET运行时仓库中的[Book of the Runtime](https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/botr/README.md)和微软开发者博客上的[Performance Improvements in .NET 6](https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-6/)、[Performance Improvements in .NET 7](https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/)和[Performance Improvements in .NET 8](https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/#whats-next)等几篇文章,上述没有覆盖到的内容推荐读者这些文章。同时算算时间,.NET 9版本引入的性能提升文章应该也要发布了。
回到文章最开始时的问题JIT编译就一定比AOT编译慢吗从启动速度上来说JIT编译当然是完败AOT编译但是在程序长时间运行各项设备JIT编译器、运行时和GC等预热完成之后则是鹿死谁手犹未可知了。

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -236,7 +236,7 @@ Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser
再重新运行配置文件就没有问题了。
![终端预览](6.webp)
![终端预览](6.png)
### PowerShell配置文件

BIN
YaeBlog/source/posts/environment-setting/6.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

View File

@ -1,12 +1,11 @@
---
title: 原神抽卡研究一
date: 2022-12-31T13:38:19.0000000
tags:
- 原神
- 学习资料
- 原神
- 学习资料
date: 2022-12-31 13:38:19
---
实际上是“概率论和随机过程”课程的期末小论文。
<!--more-->
@ -15,7 +14,7 @@ tags:
目前在市面上出现了大量以抽奖为核心盈利手段的电子游戏,在这种游戏中,获取游戏中的物品不是明码标价的购买,而是通过参加某种抽奖性质的活动。玩家花费一定金额购买参加活动的机会,每次参加都有一定的概率获得玩家想要获得的物品。在抽奖活动中,游戏设计者还会引入一种被称为 “保底” 的游戏机制:开发者向玩家群体承诺在一定的参加次数之后必然会获得到该物品。例如下面是热门游戏《原神》中获取游戏中角色 “抽奖” 活动的概率公示页面。
![](./genshin-gacha-1/2022-12-31-13-06-36-image.webp)
![](./genshin-gacha-1/2022-12-31-13-06-36-image.png)
在这个 “抽奖” 活动中,玩家可以得到三种等级的物品,在游戏中分别称为 “五星物品”、“四星物品” 和 “三星物品”。在每次的 “抽奖” 活动中,玩家必定会获得上述三种物品中的一种。为了简化问题的讨论,我们现不区分相同等级不同物品之间的不同,只考虑不同星级物品的获取概率。通过概率公示可以知道:五星物品的 “基础概率” 为0.600%,四星物品的 “基础概率” 为 5.100%;五星物品的 “综合概率” 为 1.600%,四星物品的 “综合概率” 为 13.000%。从一个玩家的角度出发,自然会存在两个问题:
@ -51,11 +50,11 @@ tags:
在总共 4842256 次抽卡记录中,获得五星物品的次数为 78493 次,于是:
![](genshin-gacha-1/2022-12-31-15-59-20-image.webp)
![](genshin-gacha-1/2022-12-31-15-59-20-image.png)
再计算一下每次参加该活动获得四星物品的平均概率:在总共 5000139 次抽卡中,获得四星物品的次数为 653200
![](genshin-gacha-1/2022-12-31-15-59-42-image.webp)
![](genshin-gacha-1/2022-12-31-15-59-42-image.png)
不难发现,在误差允许的范围内,计算出来的平均概率和游戏开发者所公布的 “综合概率” 是相同的。当参与这个游戏足够多次时,获取到五星物品和四星物品的数量就可以用这个概率来估计。
@ -63,15 +62,15 @@ tags:
为了方便讨论,再次将这个 “游戏” 简化为获得五星物品和不获得五星物品两种情况。那么这个 “抽奖” 游戏是否就能被简化为一个概率为 1.6% 的 n 次伯努利实验?不妨假设每次获得五星物品之间相互独立,这样每次获得五星物品都可以认为是首次获得五星物品,这时参加该游戏的次数就会符合概率为 1.6% 的几何分布,而为了符合保底规则,当玩家在参与到第 90 次时仍未获得五星物品,强制给予玩家一个五星的物品。画出实际数据中得到的图像和按照几何分布得到的图像。
![](genshin-gacha-1/2022-12-31-13-20-46-image.webp)
![](genshin-gacha-1/2022-12-31-13-20-46-image.png)
![](genshin-gacha-1/2022-12-31-13-21-11-image.webp)
![](genshin-gacha-1/2022-12-31-13-21-11-image.png)
不难发现假设的猜想和实际情况不相符合。在抽数小于 73 抽时,获得五星物品的概率逐渐降低,从 0.6% 左右一直降低至 0.4% 左右。当抽数大于等于 73 抽时,抽到的概率开始上升,在抽数等于 77 抽时达到最大,大约为 10.4%。随后概率开始下降,在第 91 抽时,概率等于 0。
如果在实际得到的概率关于抽数的图上再作出概率为 0.6% 的几何分布的图像前73 抽的概率图像和几何分布的图像几乎吻合。也就是说,该抽奖游戏的前 73 抽就是一个符合 P = 0.6% 的几何分布,从第 73 抽开始 “保底” 机制的修正。这就是游戏开发者口中 “基础概率” 的含义:在该抽奖游戏的前数十抽就是一个概率为 0.6% 的伯努利实验。
![](genshin-gacha-1/2022-12-31-13-24-26-image.webp)
![](genshin-gacha-1/2022-12-31-13-24-26-image.png)
从大量的实际数据出发,不难发现游戏开发者的申明同实际情况相吻合。
@ -81,7 +80,7 @@ tags:
直到作者开始写作本文之前,作者都没有意识到本文 3.2 节中的所有结论几乎都基于该假设。限于文章的篇幅原因和个人的能力问题,在本文中未对这个假设作出验证。下面给出一种验证该猜想的方法。为验证获得五星物品之间相互独立,可以通过统计方法验证下面的等式成立。
![](genshin-gacha-1/2022-12-31-16-00-10-image.webp)
![](genshin-gacha-1/2022-12-31-16-00-10-image.png)
### 展望

Some files were not shown because too many files have changed in this diff Show More