分类 technique 下的文章

1.14

为了防止自己在康paper时睡着来记一点笔记
目前在重新(?)看TACO的文章

TACO 支持在 CPU 上生成稀疏和稠密 tensor 表达式的代码
文章做的几点事情:
1. tensor 存储方法
2. iteration graph
3. merge lattices
4. 代码生成算法

由用户指定 merge 几个简单的 kernel 或者当成一个整体计算
稀疏kernel计算复杂原因:
1. sparse 数据结构维度的不同排布方式
2. sparse 下标合并

Gustafson's law:
任务总工作量为 W ,其中 p 比例的工作量可以通过并行加速,1-p 比例无法通过并行加速
当并行加速的加速比为 s 时,理论工作量为:
$$ W(s) = (1-p)W + spW $$

upd: 这个东西似乎应该这么理解:
Amdahl's law:
设串行需要时间 t, 其中 f 比例可以并行,则 N 线程加速比为:
$$S = \frac{t}{(1-f)t + \frac{f}{N} t} = \frac{1}{(1-f) + \frac{f}{N}}$$

Gustafson's law:
设 N 线程并行需要时间 ts, 其中 f 比例以并行执行,则相比单线程加速比为:
$$S = \frac{(1-f)t_s + N f t_s}{t_s} = (1-f) + N f$$

二者区别应该在于 Gustafson 从并行角度、(强调并行可以提高可解决问题规模,对应弱扩展性),而 Amdahl 从串行角度(强调并行瓶颈在于串行部分,对应强扩展性)

1.15

GPU中所有 active thread 被分配了单独的寄存器,当切换线程时不需要交换寄存器

cuda 中所有 kernel launch 都为异步
在开始和结束 CPU timer 之前都需要调用 cudaDeviceSynchronize

1.16

GPU 理论带宽计算:
V100 使用 HBM2 (double data rate) RAM, 时钟 877MHz, 4096位内存接口
理论带宽为:$$(0.877 \times 10^9 \times (4096 / 8) \times 2)\div 10^9 = 898GB/s$$

cudaMallocManaged( void** devPtr, size_t size, unsigned int flags = cudaMemAttachGlobal ) :申请 unified memory,可以从 device 和 host 上访问

Requested Global Load/Store Throughput :
kernel 需要的 gobal memory throughput,对应于等效带宽
Global Load/Store Throughput: 最小内存传输块较大,实际传输量可能超过 kernel 的需求量,记为 Global Load/Store Throughput

GPU architecture

在 V100 中 device memory 到 GPU 理论峰值带宽为 898GB/s
host memory 到 device memory 峰值带宽为 16GB/s

page locked (pinned) memory 可以获得较高host to device 带宽,可达约 12GB/s
使用 cudaHostAlloc() 进行分配
使用 cudaHostRegister() pin已经分配的内存
pinned memory 不能过量使用,分配是 heavyweight 操作

cudaMemcpy() 是阻塞操作
cudaMemcpyAsync() 非阻塞,需要 pinned host memory,需要指定 stream ID,可以与 host 的 cpu function overlap,但不能与同 stream 的 kernel overlap
两个不同的非 default stream 可以 overlap

zero copy : 需要 mapped pinned (non-pageable) memory

1.18

CUDA memory space:

for循环:

for((i = 0; i < 10; i++))
do
    echo ${i}
done
for file in $(ls .)
do
    echo ${file}
done
for i in ${a[@]} # 遍历数组元素
do
    echo $i
done
if [ $# -lt 3 ] #等价于 if (( $# < 3 ))
then
# ...
elif (( $# > 3 ))
then
# ...
else
# ...
fi
# [[]] 字符串模式匹配
if [[ "$FN" == *.@(jpg|jpeg) ]]

变量: var="name"
字符串:单引号内所有字符按原样,双引号内转义

数组: array_name = (v0, v1, v2)
下标:${array_name[index]}
全部:${array_name[@]}

参数:$0 文件名 $1 之后参数
$? : 上条命令返回值
$$ : bash进程id
$- : 当前bash选项
$* : 所有参数
"$@" : 所有参数,每个参数用引号包含
$# : 参数数量

{ pwd;ls; } > tt.out : 花括号组合多个命令,两端必须有空格
(pwd;ls) > tt.out : 普通括号在当前 shell 子shell 中运行,有相同环境变量

set -o noclobber : 重定向输出不覆盖已有文件
set +o noclobber : 重定向输出可以覆盖已有文件
set -e : 脚本中任何命令出现错误,bash退出
set -x :输出脚本中所有命令,前面加 "+"
set -u :遇到未定义变量时报错

echo "string" > file string输出到file,覆盖原有内容
echo "string" >> file 追加string到file
cd mytmp && rm * : &&分隔命令,当第一个返回值为 0 时再执行第二个命令
echo ${HOME:=/tmp} :当$HOME为空时赋值为/tmp
:- :只返回值,不赋值
:+ :存在时返回值,否则返回空,测试变量是否存在
:? :存在时返回值,否则打印并中断脚本

read TAG FN 读取一行内容,前面为单个单词,最后为剩余部分

||&& 为短路运算符

echo "line1
line2" # 输出多行文本
echo -n hello world #输出不带换行
echo -e "Hello\nWorld" #解析引号中转义符

type 'command' #指令详细信息 (bash buildin 等)
shopt #查看当前 bash 选项

ctrl + l : 将当前行移到首行
ctrl + a : 移到行首
ctrl + e : 移到行尾
alt + f : 移到单词词尾
alt + b : 移到单词词首
ctrl + k : 剪切光标位置到行尾
ctrl + u : 剪切光标位置到行首

bash 扩展

~扩展为当前用户 home
?匹配文件路径中任意单个字符
*匹配路径中任意数量字符
.*匹配隐藏文件
[...]匹配 [] 内单个字符
[^...][!...] 匹配除 ... 外单个字符
[a-zA-Z0-9] 匹配范围扩展
{1,2,3} 分别扩展成 {} 中所有值,其中不能有空格
{start..end} 扩展成 start 到 end 每个值
{start..end..stride}
${!string*}${!string@} 扩展成以 string 开头的环境变量
$(...) 和 反引号 扩展成命令结果
$((...)) 扩展成整数运算结果
量词:
?(pattern-list):匹配零个或一个模式。
*(pattern-list):匹配零个或多个模式。
+(pattern-list):匹配一个或多个模式。
@(pattern-list):只匹配一个模式。
!(pattern-list):匹配给定模式以外的任何内容。

单引号中所有字符变为普通字符
双引号中保留 $, `, \
here 文档:

<< token
text
token

输入多行字符串,支持变量替换,反斜杠转义,引号为普通字符

env : 显示所有环境变量
set : 显示所有环境变量和自定义变量

echo ${!myvar} : myvar 的最终值
unset NAME : 删除变量
export : 将用户变量变为环境变量,对所有子 shell 生效

declare -i : 声明整形变量,可以直接运算
declare -x : 等同于 export
declare -r : 声明只读变量
declare -u : 为大写字母,-l : 小写字母
declare -r : 只读变量
-p : 输出已定义变量值
-f : 输出环境中所有函数及定义
-F : 输出环境中所有函数名

let :声明变量时直接计算表达式

负责应用: gromacs && IO500

gromacs

tutorial 中提到 ccmake ,可以查看 cmake 全部选项

compile time :
GMX_SMI 必须符合target architecture

GMX_CLANG_CUDA 可能带来 performance degeneration
发现了 cpu 拓扑查看工具 hwloc

azure云

H series : CPU VM
HB : memory bandwidth
HC : dense compute
H型号 : IB 仅支持 intel MPI 5.1
HBv2, HB, HC : 全 IB 支持 (IP over IB)

GPU:
NV(visualization 意义不大), NC(GP-GPU), ND(deep learning)
A100 (unlikely)
NCV3 : 1-4 V100 16GB (older IB)
NDrv2 : 8 V100 32GB (edr IB) (NVLink interconnected)

azure cycle cloud

access restricted to single Resource group
可以在运行时修改配置

记一下看的几个spmm项目的代码结构

spbenchmark

适之学长写的
common/test.h : 测试代码,测试主函数为 testMain

merge-spmm

来自论文design principle for SPMM on GPU

test/gbspmm.cu : 主函数位置,用于处理参数,运行test

graphblas/backend/apspie/spmm.hpp:调用spmmRowKernel

graphblas/backend/apspie/kernels/spmm.hpp: 实现spmmRowKernel

graphblas/util.hpp : 定义参数等

merged path过程:
garphblas/backend/apspie/mxm.hpp : mxm ->
graphblas/backend/apspie/spmm.hpp : mergepath_spmm ->
ext/moderngpu/include/kernels/spmvcsr.cuh : SpmmCsrBinary -> SpmmCsrHost -> SpmmCsrInner ->
1.csrtools.cuh -> PartitionCsrSegReducePrealloc
2.spmvcsr.cuh -> KernelSpmmCsr