跳转至

笔记

UnimportantView: Anime Recommendation

起源与目标

  1. 看番没有形成自己的喜好,导致看到不对的,反而有副作用,
  2. 什么番可以成为精神支柱,而不是看了之后。反而精神内耗更严重了。(看了happy sugar life后,直接抑郁了)

说明

不同于恋爱番,催泪番,这样的分类。其实我更在意作品想表达的主题,作者想展现给读者什么。 无论是各种道理,还是就是某个环境,虚幻世界。

羁绊:对人的爱,爱情、亲情、友情。

何为爱的寻爱之旅

番剧名 精神内核 评语 喜爱的角色 音乐
Happy Sugar Life 守护你是我的爱语 难以理解的爱的世界里,两位迷途少女相遇,救赎,领悟爱的蜜罐生活 砂糖、盐 金丝雀、ED、悲伤小提琴

我推的孩子(第一集)

Violet Garden

羁绊的破碎和重组

BanG Dream It's my go !!!!! 初羁绊(友情,百合,重女)的破碎和reunion

病名为爱

未来日记

家有女友、渣愿

点滴恋爱

百合类的成长:终将成为你,

我心危

轮回宿命类

跨越时空也无法阻止我爱你

命运石之门

RE0

无法抵达的简单幸福未来

寒蝉鸣泣之时

魔法少女小圆

史诗类

复杂、紧张的鸿篇巨制。多非单一的精神内核可以概括。多为群像剧。

奇幻、幻想世界史诗

Fate Zero

钢炼

EVA

to do

刀剑

四谎

CLANND

龙与虎

巨人

超炮

凉宫

鲁鲁修

轻音

补番列表

  1. 物语系列

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

TLB: real pagewalk overhead

简介

TLB的介绍,请看

页表相关

理论基础

大体上是应用访问越随机, 数据量越大,pgw开销越大。

ISCA 2013 shows the pgw overhead in big memory servers.

Basu 等 - Efficient Virtual Memory for Big Memory Servers.pdf

or ISCA 2020 Guvenilir 和 Patt - 2020 - Tailored Page Sizes.pdf

机器配置

# shaojiemike @ snode6 in ~/github/hugoMinos on git:main x [11:17:05]
$ cpuid -1 -l 2
CPU:
      0x63: data TLB: 2M/4M pages, 4-way, 32 entries
            data TLB: 1G pages, 4-way, 4 entries
      0x03: data TLB: 4K pages, 4-way, 64 entries
      0x76: instruction TLB: 2M/4M pages, fully, 8 entries
      0xff: cache data is in CPUID leaf 4
      0xb5: instruction TLB: 4K, 8-way, 64 entries
      0xf0: 64 byte prefetching
      0xc3: L2 TLB: 4K/2M pages, 6-way, 1536 entries
# if above command turns out empty
cpuid -1 |grep TLB -A 10 -B 5
# will show sth like

L1 TLB/cache information: 2M/4M pages & L1 TLB (0x80000005/eax):
    instruction # entries     = 0x40 (64)
    instruction associativity = 0xff (255)
    data # entries            = 0x40 (64)
    data associativity        = 0xff (255)
L1 TLB/cache information: 4K pages & L1 TLB (0x80000005/ebx):
    instruction # entries     = 0x40 (64)
    instruction associativity = 0xff (255)
    data # entries            = 0x40 (64)
    data associativity        = 0xff (255)
L2 TLB/cache information: 2M/4M pages & L2 TLB (0x80000006/eax):
    instruction # entries     = 0x200 (512)
    instruction associativity = 2-way (2)
    data # entries            = 0x800 (2048)
    data associativity        = 4-way (4)
L2 TLB/cache information: 4K pages & L2 TLB (0x80000006/ebx):
    instruction # entries     = 0x200 (512)
    instruction associativity = 4-way (4)
    data # entries            = 0x800 (2048)
    data associativity        = 8-way (6)

OS config

default there is no hugopage(usually 4MB) to use.

$ cat /proc/meminfo | grep huge -i
AnonHugePages:      8192 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB

explained is here.

设置页表大小

other ways: change source code

  1. way1: Linux transparent huge page (THP) support allows the kernel to automatically promote regular memory pages into huge pages, cat /sys/kernel/mm/transparent_hugepage/enabled but achieve this needs some details.
  2. way2: Huge pages are allocated from a reserved pool which needs to change sys-config. for example echo 20 > /proc/sys/vm/nr_hugepages. And you need to write speacial C++ code to use the hugo page
# using mmap system call to request huge page
mount -t hugetlbfs \
    -o uid=<value>,gid=<value>,mode=<value>,pagesize=<value>,size=<value>,\
    min_size=<value>,nr_inodes=<value> none /mnt/huge

without recompile

But there is a blog using unmaintained tool hugeadm and iodlr library to do this.

sudo apt install libhugetlbfs-bin
sudo hugeadm --create-global-mounts
sudo hugeadm --pool-pages-min 2M:64

So meminfo is changed

$ cat /proc/meminfo | grep huge -i
AnonHugePages:      8192 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:      64
HugePages_Free:       64
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:          131072 kB

using iodlr library

git clone 

应用测量

Measurement tools from code

# shaojiemike @ snode6 in ~/github/PIA_huawei on git:main x [17:40:50]
$ ./investigation/pagewalk/tlbstat -c '/staff/shaojiemike/github/sniper_PIMProf/PIMProf/gapbs/sssp.inj -f /staff/shaojiemike/github/sniper_PIMProf/PIMProf/gapbs/benchmark/kron-20.wsg -n1'
command is /staff/shaojiemike/github/sniper_PIMProf/PIMProf/gapbs/sssp.inj -f /staff/shaojiemike/github/sniper_PIMProf/PIMProf/gapbs/benchmark/kron-20.wsg -n1
K_CYCLES   K_INSTR      IPC DTLB_WALKS ITLB_WALKS K_DTLBCYC  K_ITLBCYC  DTLB% ITLB%
324088     207256      0.64 733758     3276       18284      130         5.64  0.04
21169730   11658340    0.55 11802978   757866     316625     24243       1.50  0.11

平均单次开销(开始到稳定): dtlb miss read need 24~50 cycle ,itlb miss read need 40~27 cycle

案例的时间分布:

  • 读数据开销占比不大,2.5%左右
  • pagerank等图应用并行计算时,飙升至 22%
  • bfs 最多就是 5%,没有那么随机的访问。
  • 但是gemv 在65000 100000超内存前,即使是全部在计算,都是0.24%
  • 原因:访存模式:图应用的访存模式通常是随机的、不规则的。它们不像矩阵向量乘法(gemv)等应用那样具有良好的访存模式,后者通常以连续的方式访问内存。连续的内存访问可以利用空间局部性,通过预取和缓存块的方式减少TLB缺失的次数。
  • github - GUOPS can achive 90%
  • DAMOV - ligra - pagerank can achive 90% in 20M input case

gemm

  • nomal gemm can achive 100% some situation
  • matrix too big can not be filled in cache, matrix2 access jump lines so always cache miss
  • O3 flag seems no time reduce, beacause there is no SIMD assembly in code
  • memory access time = pgw + tlb access time + load data 2 cache time

gemm

the gemm's core line is

for(int i=0; i<N; i++){
   // ignore the overflow, do not influence the running time.
   for(int j=0; j<N; j++){
      for(int l=0; l<N; l++){
            // gemm
            // ans[i * N + j] += matrix1[i * N + l] * matrix2[l * N + j];

            // for gemm sequantial
            ans[i * N + j] += matrix1[i * N + l] * matrix2[j * N + l];
      }
   }
}

and real time breakdown is as followed. to do

  1. first need to perf get the detail time

bigJump

manual code to test if tlb entries is run out

$ ./tlbstat -c '../../test/manual/bigJump.exe 1 10 100'
command is ../../test/manual/bigJump.exe 1 10 100
K_CYCLES   K_INSTR      IPC DTLB_WALKS ITLB_WALKS K_DTLBCYC  K_ITLBCYC  DTLB% ITLB%
2002404    773981      0.39 104304528  29137      2608079    684        130.25  0.03

$ perf stat -e mem_uops_retired.all_loads -e mem_uops_retired.all_stores -e mem_uops_retired.stlb_miss_loads -e mem_uops_retired.stlb_miss_stores ./bigJump.exe 1 10 500
Number read from command line: 1 10 (N,J should not big, [0,5] is best.)
result 0
 Performance counter stats for './bigJump.exe 1 10 500':

          10736645      mem_uops_retired.all_loads
         532100339      mem_uops_retired.all_stores
             57715      mem_uops_retired.stlb_miss_loads
         471629056      mem_uops_retired.stlb_miss_stores

In this case, tlb miss rate up to 47/53 = 88.6%

Big bucket hash table

using big hash table

other apps

Any algorithm that does random accesses into a large memory region will likely suffer from TLB misses. Examples are plenty: binary search in a big array, large hash tables, histogram-like algorithms, etc.

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

AI Compiler

百度

秋招面试时遇到高铁柱前辈。问了相关的问题(对AI专业的人可能是基础知识)

  1. nvcc编译器不好用吗?为什么要开发tvm之类的编译器?
  2. 答:首先,nvcc是类似与gcc, msvc(Microsoft Visual C++) 之类的传统的编译器,支持的是CUDA C/C++ 代码。
  3. 但是tvm编译器是张量编译器,支持的是python之类的代码,将其中的网络设计,编译拆解成各种算子,然后使用cudnn或者特定硬件的高效机器码来执行。

蔚来

数字信号处理器 (Digital signal processor)

HLO 简单理解为编译器 IR。

TVM介绍

https://tvm.apache.org

  1. TVM解决的问题:
  2. 2017年,deploy Deep learning(TF,Pytorch) everywhere(hardware).
  3. Before TVM,
    1. 手动调优:loop tiling for locality.
    2. operator fusion 算子融合。虽然性能高,但是部署不高效
  4. 编译优化思路引入深度学习
  5. 定义了算子描述到部署空间的映射。核心是感知调度空间,并且实现compute/schedule 分离
  6. TVM当前的发展
  7. 上层计算图表示:NNVM Relay Relax
  8. 底层优化方式:manual -> AutoTVM(schedule最优参数的搜索,基于AI的cost model) -> Ansor(也不再需要手动写AutoTVM模版,使用模版规则生成代码)
  9. TVM的额外工作
  10. HeteroCL: TVM + FPGA

  1. output Fusion
  2. 减少Global Memory Copy

把中间算子库替换成编译器?

暂时不好支持张量

AI自动调整变化来调优

自动调参。缺点:

  1. 需要人工写模版
  2. 人工导致解空间变小

随机各级循环应用优化策略(并行,循环展开,向量化

介绍了Ansor效果很好

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

Graph Algorithms: Pagerank

Pagerank

  1. Network and social network can be identified as a weighted graph
  2. How to do the important ranking is Pagerank

how to design a graph when pr executing memory access jump data-array very random?

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

https://zhuanlan.zhihu.com/p/137561088

Python: DataStructure

开发基础

size 大小

len(day)

空值判断

strings, lists, tuples

# Correct:
if not seq:
if seq:

# Wrong:
if len(seq):
if not len(seq):

中断捕获

try:
    # sth
except Exception as e:
    # 可以使用rich包
    pprint.pprint(list)
    raise e
finally:
    un_set()

for

间隔值

调参需要测试间隔值

for i in range(1, 101, 3):
    print(i)

遍历修改值

  • 使用 enumerate 函数结合 for 循环遍历 list,以修改 list 中的元素。
  • enumerate 函数返回一个包含元组的迭代器,其中每个元组包含当前遍历元素的索引和值。在 for 循环中,我们通过索引 i 修改了列表中的元素。
# 对于 二维list appDataDict
baseline = appDataDict[0][0] # CPU Total
for i, line in enumerate(appDataDict):
    for j, entry in enumerate(line):
        appDataDict[i][j] = round(entry/baseline, 7)

itertools

itertools --- 为高效循环而创建迭代器的函数

for a,b,c in permutations((a,b,c)):

小数位

x = round(x,3)# 保留小数点后三位

String 字符串

%c  格式化字符及其ASCII码
%s  格式化字符串
%d  格式化整数
%u  格式化无符号整型
%o  格式化无符号八进制数
%x  格式化无符号十六进制数
%X  格式化无符号十六进制数(大写)
%f  格式化浮点数字,可指定小数点后的精度
%e  用科学计数法格式化浮点数
%E  作用同%e,用科学计数法格式化浮点数
%g  %f和%e的简写
%G  %F  %E 的简写
%p  用十六进制数格式化变量的地址
print("My name is %s and weight is %d kg!" % ('Zara', 21))

string <-> list

' '.join(pass_list) and pass_list.split(" ")

对齐"\n".join(["%-10s" % item for item in List_A])

开头判断

text = "Hello, world!"

if text.startswith("Hello"):
    print("The string starts with 'Hello'")
else:
    print("The string does not start with 'Hello'")

格式化

Python2.6 开始,通过 {}: 来代替以前的 %

>>>"{} {}".format("hello", "world")    # 不设置指定位置,按默认顺序
'hello world'

>>> "{1} {0} {1}".format("hello", "world")  # 设置指定位置
'world hello world'

# 字符串补齐100位,<表示左对齐
variable = "Hello"
padded_variable = "{:<100}".format(variable)

数字处理

print("{:.2f}".format(3.1415926)) # 保留小数点后两位

{:>10d} 右对齐 (默认, 宽度为10)
{:^10d} 中间对齐 (宽度为10)

NumPy

布尔索引

保留 frame_indices 中的值小于 max_frame 的元素。

frame_indices = frame_indices[frame_indices < max_frame]

容器:List

https://www.runoob.com/python/python-lists.html

初始化以及访问

list = ['physics', 'chemistry', 1997, 2000]
list = []          ## 空列表
print(list[0])

切片

格式:[start_index:end_index:step]

不包括end_index的元素

二维数组

list_three = [[0 for i in range(3)] for j in range(3)]

//numpy 创建连续的可自动向量化线程并行
import numpy as np
# 创建一个 3x4 的数组且所有值全为 0
x3 = np.zeros((3, 4), dtype=int)
# 创建一个 3x4 的数组,然后将所有元素的值填充为 2
x5 = np.full((3, 4), 2, dtype=int)

排序

# take second element for sort
def takeSecond(elem):
    return elem[2]

LCData.sort(key=takeSecond)

# [1740, '黄业琦', 392, '第 196 场周赛'],
# [1565, '林坤贤', 458, '第 229 场周赛'],
# [1740, '黄业琦', 458, '第 229 场周赛'],
# [1509, '林坤贤', 460, '第 230 场周赛'],
# [1740, '黄业琦', 460, '第 230 场周赛'],
# [1779, '黄业琦', 558, '第 279 场周赛'],

对应元素相加到一个变量

tmp_list = [[],[],[],[]]
# 注意不需要右值赋值
[x.append(copy.deepcopy(entry)) for x,entry in zip(tmp_list, to_add)]
两个list对应元素相加

对于等长的

list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8, 9, 10]

result = [x + y for x, y in zip(list1, list2)]
print(result)

如果两个列表的长度不同,你可以使用zip_longest()函数来处理它们。zip_longest()函数可以处理不等长的列表,并使用指定的填充值填充缺失的元素。

from itertools import zip_longest

list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8]

result = [x + y for x, y in zip_longest(list1, list2, fillvalue=0)]
print(result)

如果是二维list

list1 = [[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]]

list2 = [[10, 11, 12],
        [13, 14, 15]]

rows = max(len(list1), len(list2))
cols = max(len(row) for row in list1 + list2)

result = [[0] * cols for _ in range(rows)]

for i in range(rows):
    for j in range(cols):
        if i < len(list1) and j < len(list1[i]):
            result[i][j] += list1[i][j]
        if i < len(list2) and j < len(list2[i]):
            result[i][j] += list2[i][j]

print(result)

# 将一个二维列表的所有元素除以一个数A
result = [[element / A for element in row] for row in list1]

容器:元组Tuple

  • 元组和列表类似,但是不同的是元组不能修改,但可以对元组进行连接组合,元组使用小括号。
  • 元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用。
#创建元组
tup = (1, 2, 3, 4, 5)
tup1 = (23, 78);
tup2 = ('ab', 'cd')
tup3 = tup1 + tup2

容器:Dict

初始化

>>> tinydict = {'a': 1, 'b': 2, 'b': '3'}
>>> tinydict['b']
'3'

empty dict

a= {}
a=dict()
a_dict = {'color': 'blue'}
for key in a_dict:
 print(key)
# color
for key in a_dict:
    print(key, '->', a_dict[key])
# color -> blue
for item in a_dict.items():
    print(item)
# ('color', 'blue')
for key, value in a_dict.items():
 print(key, '->', value)
# color -> blue

key和value支持tuple元组,常用于保存函数入参与结果映射

类似c++ 的 pair<int,int>

class RoPE3D(nn.Module):

    def __init__(self, freq=10000.0, interpolation_scale=(1, 1, 1)):
        super().__init__()
        self.cache = {}

    def get_cos_sin(self, dim, seq_len, device, dtype, interpolation_scale=1):
        if (dim, seq_len, device, dtype) not in self.cache:
            # ...
            self.cache[dim, seq_len, device, dtype] = (cos, sin)
        return self.cache[dim, seq_len, device, dtype]
  1. 关于 if (dim, seq_len, device, dtype) not in self.cache 的条件判断
  2. 这里检查的是 整个元组作为字典的键 是否存在,而不是检查单个元素。
  3. 例如:字典 self.cache 的键是类似 (128, 100, "cuda", torch.float32) 的元组。
  4. 当且仅当 (dim, seq_len, device, dtype) 这个完整元组不在字典中时,条件为 True,才会执行后续代码。
  5. 如果元组中的任意一个元素不同(如 seq_len 变化),则会被视为不同的键。

  6. 关于 self.cache[...] = (cos, sin) 的赋值

  7. 这是一个 将元组作为键,元组作为值 的字典设计。
  8. 键是 (dim, seq_len, device, dtype) 的四元组,用于唯一标识一组计算参数。
  9. 值是对应的 (cos值张量, sin值张量) 的二元组,因为这两个张量总是成对出现。
  10. 例如:self.cache[(128, 100, "cuda", float32)] = (cos_tensor, sin_tensor)

进一步解释这种设计的目的

  • 缓存机制:避免重复计算相同参数的 cos/sin,不同参数组合会生成不同的键。
  • 元组作为键的合法性:Python允许用不可变类型(如元组)作为字典键。
  • 高效查询:通过参数元组直接定位到预计算结果,提升性能。

你可以通过一个简单例子验证:

cache = {}
key = (128, 100, "cuda", "float32")
cache[key] = ("cos", "sin")

print( (128, 100, "cuda", "float32") in cache )  # True(完全匹配)
print( (128, 200, "cuda", "float32") in cache )  # False(seq_len不同)

key 支持tuple元组, 但是不能json.dump()

bblHashDict[(tmpHigherHash,tmpLowerHash)]=tmpBBL

但是这样就不支持json.dump, json.dump() 无法序列化 Python 中元组(tuple)作为字典的 key,这会导致 json.dump() 函数在写入此类字典数据时会进入死循环或陷入卡住状态

del tinydict['Name']  # 删除键是'Name'的条目
tinydict.clear()      # 清空字典所有条目
del tinydict          # 删除字典

tinydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}

tinydict['Age'] = 8 # 更新
tinydict['School'] = "RUNOOB" # 添加

合并

dict1 = {'a': 10, 'b': 8} 
dict2 = {'d': 6, 'c': 4} 

# dict2保留了合并的结果
dict2.update(dict1)
print(dict2)
{'d': 6, 'c': 4, 'a': 10, 'b': 8}

判断key 是否存在

以下是两种常用的方法:

方法一:使用in操作符: in操作符返回一个布尔值,True表示存在,False表示不存在。

Copy code
my_dict = {"key1": "value1", "key2": "value2", "key3": "value3"}

# 判断是否存在指定的键
if "key2" in my_dict:
    print("Key 'key2' exists in the dictionary.")
else:
    print("Key 'key2' does not exist in the dictionary.")

方法二:使用dict.get()方法: dict.get()方法在键存在时返回对应的值,不存在时返回None。根据需要选择适合的方法进行判断。

Copy code
my_dict = {"key1": "value1", "key2": "value2", "key3": "value3"}

# 判断是否存在指定的键
if my_dict.get("key2") is not None:
    print("Key 'key2' exists in the dictionary.")
else:
    print("Key 'key2' does not exist in the dictionary.")

这两种方法都可以用来判断字典中是否存在指定的键。

容器:set

无序不重复序列

初始化

a=  set() # 空set

thisset = set(("Google", "Runoob", "Taobao"))
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # 这里演示的是去重功能

thisset.add("Facebook")

s.remove( x )
# 使用 discard() 移除元素
my_set.discard(3) # 如果元素不存在则什么也不做。也不会报错 KeyError
a.clear()

合并
x = {"apple", "banana", "cherry"}
y = {"google", "runoob", "apple"}

z = x.union(y) 

print(z)
# {'cherry', 'runoob', 'google', 'banana', 'apple'}

类型转换

list2set
setL=set(listV)
set2list
my_set = {'Geeks', 'for', 'geeks'}

s = list(my_set)
print(s)
# ['Geeks', 'for', 'geeks']

参考文献

https://blog.csdn.net/weixin_63719049/article/details/125680242

Benchmark

导言

以现实中实际使用的应用为基础,根据其领域和应用计算特点来分类。

Perf

简介

  • pref
  • kperf : ./kperf_static --pid 1043785 --topdown --cache --tlb --imix --uncore --duration 3 --iter-num 1

Intel SDM(Software Developer's Manual)

Introduction

This set consists of

volume Descriptions pages(size)
volume 1 Basic Architecture 500 pages(3MB)
volume 2 (combined 2A, 2B, 2C, and 2D) full instruction set reference 2522 pages(10.8MB)
volume 3 (combined 3A, 3B, 3C, and 3D) system programming guide 1534 pages(8.5MB)
volume 4 MODEL-SPECIFIC REGISTERS (MSRS) 520 pages

volume3: Memory management(paging), protection, task management, interrupt and exception handling, multi-processor support, thermal and power management features, debugging, performance monitoring, system management mode, virtual machine extensions (VMX) instructions, Intel® Virtualization Technology (Intel® VT), and Intel® Software Guard Extensions (Intel® SGX).

AMD64 Architecture Programmer's Manual (3336 pages)

more graph and easier to read.

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html

Make

导言

虽然大型项目会使用cmake,手写makefile的情况比较少,但是基本语法还是要熟悉的。