git merge vs rebase

git 修改之前的某次commit 注释和常见问题和解决方法_git修改某次commit的comment-CSDN博客

git rebase 用法详解与工作原理 | Shall We Code?

git merge

有两个分支 branchA branchB ,初始时,branchA在C1 节点 基于此节点,拉出branchB

以下操作按照时间顺序

对branchB进行修改 C2

对branchA进行修改 C3

对branchB进行修改 C4

将branchB merge 到branch A

可以看出merge的树是以不同branch体现的,不能完整体现时间顺序

git rebase

此时 reset一下merge操作:

随后将branchB 通过rebase的方式合并到branchA

可以看出 先将branchA的head移动到最新的branchB,再将branchA的修改添加回branchA。合并操作不会产生新的节点

对于单独一个分支的rebase

假如我们对当前分支的某次历史提交执行 rebase,其结果就是会将这次提交之后的所有提交重新应用在当前分支,在交互模式下,即允许我们对这些提交进行更改。

git rebase -i HEAD~4

可以看到后面的提交都变了ID

git rebase -i HEAD~6

多rebase几个,但是修改还是修改同样的地方,那还是修改后的节点ID改变

利用rebase 修改历史提交的comment

对于一直使用rebase操作的代码,修改历史comment十分简单,

比如我想修改branchB C2 那次的log

git rebase -i HEAD~3

这件事不会影响branchB 也不会影响branchA的提交顺序。但是会导致branchA重新增加comment的提交以及之后的提交的hashID改变

对于使用merge的代码进行message修改,就比较复杂

此时要修改branchB 中C2 节点 9d3282c 的名字

git rebase -i HEAD~3

似乎列出的是branchA分支上最后三次的操作,当然也包含branchB上的

会失败,原因是:rebase之后相当于把branchB C2 C4两个节点的内容加入到 branchA C3这个节点后,在对比banechB C2 9d3282c 和 22279e0时 出现了不一致的问题。在此猜测 能merge成功是因为merge对比的是8f4cda7 和 22279e0。

先abort这次rebase, 恢复原样

git rebase -i HEAD~2 去修改C4节点 message 8f4cda7 也不行, 感觉是branchA已经包含了branchB那些修改。再搞个干净的分支。

新来一个分支 验证merge的代码如何修改message

现在想修改branchC newnode2 0b21277 那次message

git rebase -i HEAD~2

首先 修改了该提交的message, 其次,也运行了rebase。 将branchC的改动接到了branchA后面 (注意 如果是rebase branchC 那么是把branchA改动接到C后面。 但是我们这里运行rebase head 也就是rebase branchA 那么 就是把C的改动接到A后面。

反正本地rebase 不对劲就–abort

intptr VS int32 or int64

intptr int32
在32位机器下等同于int32 占32位,
在64位机器下等同于int64 占64位
占32位
指针偏移的时候用intptr
比如intptr strideS; pSrc += strideS
此时strideS 存储的数还是一样大小,也不会超出int32的范围,至少写汇编的时候能注意到这里
但是存储地址的时候 就得用intptr address = &(int a)
计数的时候用int32就够了。
比如for (int32 i = 0; i < (int32)120;i++)
申请内存大小的时候 buffersize也是用int32
运算的时候也是int32

CMake 简单用法

编译:

编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件( .o 文件或 .obj 文件)。

链接:

链接时,主要是链接函数和全局变量。所以,我们可以使用这些中间目标文件( .o 文件或 .obj 文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便。所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

CMake 定位

其他Make 工具 CMake
GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp CMake
对应着不同的Makefile 采用平台统一的CMakeLists.txt 生成自适应的Makefile
make Makefile 编译 :不同产商的make各不相同,也有不同的语法,但其本质都是在 “文件依赖性”上做文章 make Makefile 编译

CMake用法

Makefile

工程编译规则,描述了整个工程的编译和链接等规则。其中包含了哪些文件需要编译,哪些文件不需要编译,哪些需要先编译,哪些需要重建等。

在生成makefile这步时 会进行语法检查么 会进行.cpp 到.o 么 ?不会。makefile只是编译规则 还没开始编译。makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。

Make

make工具就根据makefile中的命令进行编译和链接的。生成.o 这类文件,再进一步链接生成.exe这类文件。

参考

Makefile 简介 - Makefile基本概念介绍 - Makefile 简明教程 | 宅学部落

概述 &mdash; 跟我一起写Makefile 1.0 文档

Linux Makefile:使用CMake生成Makefile文件_cmake写makefile-CSDN博客

常见操作的耗时

在c release层面

分辨率 H*W 1280 720 耗时(MS) 包含基本操作
3*3 avg filter 普通写法 1.02 读写 +: 8  / :1
5*5 avg filter 普通写法 2.54 读写 + 24 /:1
3*3 winsum avg filter 0.93 读写 +: 2 /: 1 other prepare for window
5*5 winsum avg filter 0.94 读写 +: 2 /: 1 other prepare for window
2 to 1 down sample 0.23 读写
1/4 H*W upsample (video filter) 1.52 读写 +:4  / :5
1/16 H*W upsample(video filter) 1.51 读写 +:4  / :5
1/4 H*W upsample (specialRatio_bilinear up) 0.60 读写 +:4  / :1
1/16 H*W upsample (specialRatio_bilinear up) 0.44 读写 +:4  / :1
3*3 avg filter 1/4 HxW 普通写法 0.26
5*5 avg filter 1/4 HxW winsum 0.24

手写单指令多数据 armv8 加速效果

分辨率 H*W 1280 720 耗时(MS) 包含基本操作
3*3 avg filter 普通写法
5*5 avg filter 普通写法
3*3 winsum avg filter 0.13
5*5 winsum avg filter 0.14
2 to 1 down sample
1/4 H*W upsample (video filter)
1/16 H*W upsample(video filter)
1/4 H*W upsample (specialRatio_bilinear up)
1/16 H*W upsample (specialRatio_bilinear up)
3*3 avg filter 256x144 winsum 0.01
5*5 avg filter  256x144 winsum 0.01

单指令多数据常用操作 intrinsic

mla 乘加或者乘减比分开做要快

循环费时

arm intrinsic 指令查询技巧

查询指令的网址

ARM Neon Intrinsics各函数介绍_arm neon intrinsic 函数_June_Hou的博客-CSDN博客

https://developer.arm.com/architectures/instruction-sets/intrinsics/#q=vmovl_high_u16

总的来说

正常指令 操作64位 指令后加q了的话128位

长指令 指令后面加l ,结果比两个操作数要长

宽指令 指令后面加w 两种数据类型不一样相加减等 生成的数据类型取较宽的那个

窄指令 指令后面加hn 对应的长指令 加减之后 结果比原本两个一样类型的输入要窄

饱和指令 指令后面加q 自动限制在数据范围内

基本运算

乘法 mul

乘加 mla

加法 add

减法 sub

位移 shl shr 

取大小 min max

绝对值 vabs 

取反 vneg

和查表有关的:tb 但只支持表格很小?unit8x8这种table + index

比较

vceq (vector compare equal)

vcge a>=b? (Greater equal

vcle   a<=b? 

Vcgt a>b greater than

Vclt a<b

Vcage |a| >= |b| (vector compare absolute greater equal

r = |a - b| vabd vector absolute difference 

R = a + |b -c| vaba absolute difference and accumulate

位运算

r = a|(~b) vorn_s8   or not

R = ~a & b vbic_s8 bitwise clear

R = a ^ b veor_s8 exclusive or

R = a | b vorr_s8 or

R = a & b vand_s8 and

R = ~a vmvn_s8

赋值or读写

vdup_n_s8 duplicate a scalar into every element of vector ??? Dup mov???

Dup是把一个数据复制多份的关键词

Ld 则是正常load 的关键词

Mov是 拿到一些高位 或者地位 就是操作数和结果位宽不同?(好像也不一定 偶尔和dup等价?

Get是 把unit816 拆成uint88 x2 这种 位宽相同 并行个数不同 vget_high vget_low

cvt convert数据类型

combine 把8个*2 合并成16个

int8x16_t vcombine_s(int8x8_t a,int8x8_t b)

create 从uint64 create uint8x8

banding artifact

banding 现象

单帧

图像平坦渐变区域,出现条带状变化

多帧

随着时间推进,条带状变化移动

banding 造成原因和解决办法

量化

色彩空间转化时,中间空间的量化: RGB 2 YUV 2 RGB

中间运算中的量化: Y‘ = kY + mU + nV

尽量避免中间运算的量化,尤其避免中间运算的多步量化

拉伸

拉伸会导致原来+1 的数据+2 Y‘ = kY k>1

压缩会导致原来不规则(-1 -2 随机)变化的数据 规则的-1 Y‘ = kY k<1

不合理的拉伸公式:UV = f(y), 导致在RGB域无法连续变化

避免映射曲线的斜率过大或者过小,注意多步变化相当于曲线相乘,进一步增大斜率

过于规则

平坦区域如果变化过于规则,视觉也能看到banding

加噪音

多帧

随着时间的推移,输入在渐变,但是经过上述的异常引入,表现出banding 移动

测试阶段

  1. C++ 多次运行,测试结果的一致性

  2. 开启这些诊断

  3. 长时间开启,测试内存

  4. 汇编和C++测试一致性

  5. 视频任务,测试各种分辨率(不同视频不同分辨率,同一个视频中间切换分辨率)

  6. 视频任务,测试其中某些帧内存申请失败,会不会导致整个线程挂掉

  7. 测试同其他feature 一同运行结果是否正常

  8. 测试不同机型下运行时间

DDPM_DDIM_SDE_CompVis

DDPM

Denoising Diffusion Probabilistic Models

https://github.com/betterlmy/ddpm_abarankab

公式原理

正向一步步加噪音:

beta是一个设定好的和t有关的超参数,噪音就是随机高斯噪音

正向一步得到加噪结果

网络训练去噪器
估计出当前噪音,得到Xt-1

总的来说

代码实现

训练过程

推理过程

DDIM

DENOISING DIFFUSION IMPLICIT MODELS

https://github.com/ermongroup/ddim

论文原理

DDPM在采样的时候,需要利用到xt-1 扩散到xt的知识,导致sample速度过慢,而DDIM可以只利用predicted X0 Xt,去求Xt-1,这样就不要求一步步采样了。

reverse过程

代码实现

训练过程,和DDPM一样

推理过程

SDE

论文原理

SDE时间上连续 ,正向和逆向推导过程

涵盖了之前的score base 和ddpm

score base VE

ddpm VP

结合上述两种扩散方式 提出sub-VP SDE 目的是which perform particularly well on

likelihoods

PC采样:

用SDE数值求解预测出结果,再用分数估计修正结果。这部分也有一些实验性结论,比如correct一步还是n步。结合了两种采样方式 *unifies and improves over existing sampling methods for score-based models.

PC的原因

纠正离散步长不准确?

ODE

就是一种和SDE有同样边缘概率分布的采样方式 likelihood fast adaptive sampling via black-box ODE solvers, flexible data manipulation via latent codes, a uniquely identifiable encoding, and notably, exact likelihood computation.

controllable generation

对于score模型 只要知道了 每个时刻condition 的score 就可以根据condition生成图片了,总之就是额外或者利用domain信息,得到一个跟condition有关的score,放到采样过程中就行。主要应用有,分类图片生成,图片补全,图片上色。

这里这些condition都是sample时候加进去的,不涉及估计score的那个训练阶段。

代码实现

怎么训练分数网络

score 本质上还是和noise z相关的的一个估计

怎么采样

PC采样的框架

不同数值求解器的predictor

不同数值求解器的correcter,只截取了部分 还有很多

https://www.bilibili.com/video/BV1Dd4y1A7oz/?spm_id_from=333.999.0.0&vd_source=857061537338948659f6d0f1f3868d83

https://www.bilibili.com/video/BV19M411z7hS/?spm_id_from=333.999.0.0&vd_source=857061537338948659f6d0f1f3868d83

https://www.bilibili.com/video/BV1jg411Q7bQ/?spm_id_from=333.337.search-card.all.click&vd_source=857061537338948659f6d0f1f3868d83

CompVis

论文思想

High-Resolution Image Synthesis with Latent Diffusion Models

利用预先训练好的encoder decoder,将图像映射到latent space上再做DM,这样节省计算资源,因此可以训练高清图片。

在去噪器的结构里加入cross-attention layers 实现更丰富的控制生成。

https://github.com/CompVis/latent-diffusion