Big-Endian & Little-Endian

问题是否有意义

鸡蛋从哪头打破,怎么会有哪种更合适呢?对个人生活和社会发展又有什么意义呢?Swift写这段故事,其实是讽刺当时法国和英国的时政,认为真正重要的事情得不到关注、而在一些毫无意义的事情上争论不休。

各个阵营的选择

Motorola的PowerPC系列CPU采用Big-Endian方式存储数据,

而Intel的x86系列则采用Little-Endian方式存储数据。

JAVA虚拟机中多字节类型数据的存放顺序,也就是JAVA字节序是Big-Endian。

很多的ARM,DSP(Digital signal processor)都为小端模式。有些ARM处理器还可以随时在程序中(在ARM Cortex 系列使用REV、REV16、REVSH指令)进行大小端的切换。

忽略大小端的情况

得益于高级语言的发展,在现在的软件开发基本不需关心字节序(除非是socket编程),如Java这类跨平台移植的语言由虚拟机屏蔽了字节序问题。

对于大小端的处理也和编译器的实现有关,在C语言中,默认是小端(但在一些对于单片机的实现中却是基于大端,比如Keil 51C),Java是平台无关的,默认是大端。在网络上传输数据普遍采用的都是大端

大小尾端程序

华为鲲鹏AArch64 和 Intel x86 都是little-endian


需要进一步的研究学习

暂无

遇到的问题

暂无

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

参考文献

LLVM-MCA: Install&RunTests

github

https://github.com/llvm/llvm-project/tree/main/llvm/tools/llvm-mca

Quick Start

安装

下载可执行文件上传服务器,解压

安装遇到的问题

  1. cannot find libtinfo.so.5
    1. sudo apt install libncurses5
    2. ln -s /usr/lib/libncursesw.so.6 /usr/lib/libtinfo.so.5 或者类似的 ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
    3. 在/snap/core下找到了,但是这是什么目录?是之前Ubuntu的包管理工具,但是已经不用了。

从源码安装

node5

由于之后要写代码的,还是从头安装更好。

1
2
3
4
5
6
cd llvm-project
mkdir build
cmake -S llvm -B build -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS="clang;llvm-mca" -DCMAKE_INSTALL_PREFIX="~/Install/llvm" -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_ASSERTIONS=On
cd build
make -j32
make install

kunpeng

1
2
cmake -S llvm -B build -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS=all -DCMAKE_INSTALL_PREFIX="~/Install/llvm" -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_ASSERTIONS=On
#change cmake or -DLLVM_ENABLE_PROJECTS="all"

error

1
2
3
g++: error: unrecognized command line option ‘-mllvm’
g++: error: unrecognized command line option ‘--tail-merge-threshold=0’
g++: error: unrecognized command line option ‘-combiner-global-alias-analysis’

change

1
cmake -S llvm -B build -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS="clang;llvm-mca" -DCMAKE_INSTALL_PREFIX="~/Install/llvm" -DLLVM_TARGETS_TO_BUILD=AArch64 -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_ASSERTIONS=On

使用

1
clang foo.c -O2 -target x86_64-unknown-unknown -S -o - | llvm-mca -mcpu=btver2

由于不是X86,llc --version 查看到target是 aarch64-unknown-linux-gnu

1
clang /home/shaojiemike/Download/llvm-project-main/lldb/test/API/lang/c/forward/foo.c -O2 -target aarch64-unknown-linux-gnu -S -o -|llvm-mca -timeline -show-encoding -all-stats -all-views

生成汇编代码,并默认管道到llvm-mca,并开启所有输出。

可以看出是用TSV110Unit的port,默认cpu是tsv110

名词解释

ALU/BRU

算数逻辑单元 ALU 负责处理整数运算指令. 跳转处理单元BRU 负责处理跳转指令. BRU 可以与 ALU 合并, 复用 ALU 的逻辑来计算跳转指令的条件和跳转地址, 也可以作为一个单独的功能单元接入到流水线中.

MDU

乘除法单元 MDU (mult-divide unit)

需要进一步的研究学习

  1. llvm-mca微指令怎么实现的,怎么把汇编变成微指令
  2. 在view里加memory的实现
  3. 考虑了cache命中等影响 https://github.com/andreas-abel/uiCA uops
  4. 鲲鹏架构 https://bbs.huaweicloud.com/community/usersnew/id_1513665626477516

遇到的问题

  1. llvm-mca -mcpu=help竟然会卡住,不知道为什么
  2. 所以说是华为已经写了一个叫tsv110的,实现2个功能?

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

参考文献

样例输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
Iterations:        100
Instructions: 200
Total Cycles: 70
Total uOps: 200

Dispatch Width: 4
uOps Per Cycle: 2.86
IPC: 2.86
Block RThroughput: 0.5


No resource or data dependency bottlenecks discovered.


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)
[7]: Encoding Size

[1] [2] [3] [4] [5] [6] [7] Encodings: Instructions:
1 1 0.33 4 20 00 80 52 mov w0, #1
1 1 0.50 U 4 c0 03 5f d6 ret


Dynamic Dispatch Stall Cycles:
RAT - Register unavailable: 0
RCU - Retire tokens unavailable: 0
SCHEDQ - Scheduler full: 0
LQ - Load queue full: 0
SQ - Store queue full: 0
GROUP - Static restrictions on the dispatch group: 0


Dispatch Logic - number of cycles where we saw N micro opcodes dispatched:
[# dispatched], [# cycles]
0, 20 (28.6%)
4, 50 (71.4%)


Schedulers - number of cycles where we saw N micro opcodes issued:
[# issued], [# cycles]
0, 3 (4.3%)
2, 1 (1.4%)
3, 66 (94.3%)

Scheduler's queue usage:
No scheduler resources used.


Retire Control Unit - number of cycles where we saw N instructions retired:
[# retired], [# cycles]
0, 3 (4.3%)
2, 1 (1.4%)
3, 66 (94.3%)

Total ROB Entries: 128
Max Used ROB Entries: 59 ( 46.1% )
Average Used ROB Entries per cy: 32 ( 25.0% )


Register File statistics:
Total number of mappings created: 100
Max number of mappings used: 29


Resources:
[0.0] - TSV110UnitAB
[0.1] - TSV110UnitAB
[1] - TSV110UnitALU
[2] - TSV110UnitFSU1
[3] - TSV110UnitFSU2
[4.0] - TSV110UnitLdSt
[4.1] - TSV110UnitLdSt
[5] - TSV110UnitMDU


Resource pressure per iteration:
[0.0] [0.1] [1] [2] [3] [4.0] [4.1] [5]
0.66 0.67 0.67 - - - - -

Resource pressure by instruction:
[0.0] [0.1] [1] [2] [3] [4.0] [4.1] [5] Instructions:
0.33 - 0.67 - - - - - mov w0, #1
0.33 0.67 - - - - - - ret


Timeline view:
Index 0123456789

[0,0] DeER . . mov w0, #1
[0,1] DeER . . ret
[1,0] DeER . . mov w0, #1
[1,1] D=eER. . ret
[2,0] .DeER. . mov w0, #1
[2,1] .DeER. . ret
[3,0] .D=eER . mov w0, #1
[3,1] .D=eER . ret
[4,0] . DeER . mov w0, #1
[4,1] . D=eER . ret
[5,0] . D=eER . mov w0, #1
[5,1] . D=eER . ret
[6,0] . D=eER . mov w0, #1
[6,1] . D=eER . ret
[7,0] . D=eER . mov w0, #1
[7,1] . D==eER. ret
[8,0] . D=eER. mov w0, #1
[8,1] . D=eER. ret
[9,0] . D==eER mov w0, #1
[9,1] . D==eER ret


Average Wait times (based on the timeline view):
[0]: Executions
[1]: Average time spent waiting in a scheduler's queue
[2]: Average time spent waiting in a scheduler's queue while ready
[3]: Average time elapsed from WB until retire stage

[0] [1] [2] [3]
0. 10 1.7 1.7 0.0 mov w0, #1
1. 10 2.0 2.0 0.0 ret
10 1.9 1.9 0.0 <total>

HPCthreeLaws

Amdahl’s law

默认问题大小是固定的,导致最终可加速的倍率有上限

s是并行部分的加速比,p是可并行部分。

Gustafson’s law

默认问题总时间固定,比如串行时间a,并行时间b,并行部分加速就是核数n, 并行部分就是$F=\frac{a}{a+b}$。
$$执行时间=a+b$$
$$系统总执行时间=a+nb$$
$$S=\frac{a+nb}{a+b}=F+n(1-F)$$
意义在于,当并行部分较多时,加速比与核数成正比。

Sun-Ni’s Law

内存受限系统的加速比

这里的具体计算去看wiki

需要进一步的研究学习

暂无

遇到的问题

暂无

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

参考文献

Static Code Analyzer on Kunpeng Overview

Static Code Analyzer Overview

What Is Static Analysis?

一种通过在程序运行之前自动检查源代码的调试方法。

What Is Static Code Analysis?

经常和source code analysis结合(貌似sourcetail的代码结构分析?

可以分析addresses weaknesses漏洞

IPC - Instructions per cycles

Throughput and Critical Path Analysis

好吧,都是机密,就不写了。

Chen advise

提高访存的方法 C-AMAT

目标

机密

需要进一步的研究学习

暂无

遇到的问题

暂无

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

参考文献

Huawei Kunpeng workload

9.3

Top-down

TMA intel 2014论文

PMU-tools

PMU-event

  1. userspace
  2. system call

JQC

基于先验知识的

TSV taishan 9110

OSACA

IACA

需要进一步的研究学习

暂无

遇到的问题

  1. 乱序执行固件
    1
    2
    3
    int ptag

    vfp ptag
  2. 后端解释黑盒

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

参考文献

IPCC Preliminary SLIC Case1/2/3

case 1

default

enforce_intel

case 2

default

enforce_intel

case 3

default

enforce_intel

需要进一步的研究学习

暂无

遇到的问题

暂无

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

参考文献

IPCC Preliminary SLIC Optimization 6: Non-blocking MPI

非阻塞MPI

MPI_Send & MPI_receive

MPI_AllTogether()更慢,需要4s

手动向量化对齐

debug

1
2
vx = _mm256_set_pd(x); #改成
vx = _mm256_set_pd(x+3,x+2,x+1,x);

发现不对劲,打印更多输出。第一次循环肯定是对的因为和DBL_MAX比较。

需要进一步的研究学习

为什么明明有56GB的IB网,传输速度还是这么慢呢?写比较慢?

7*8=56 8条通道

遇到的问题

暂无

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

参考文献

Hybrid Multithreaded/OpenMP + MPI parallel Programs

混合编程需要注意的问题

https://www.nhr.kit.edu/userdocs/horeka/batch_slurm_mpi_multithread/ 看这个

还有个ppt 16

google hydrid openmpi openmp

intelmpi 编译

这里值得要注意的是,似乎直接用mpif90/mpicxx编译的库会报错,所以需要用

icc -openmp hello.cpp -o hello -DMPICH_IGNORE_CXX_SEEK -L/Path/to/mpi/lib/ -lmpi_mt -lmpiic -I/path/to/mpi/include
其中-DMPICH_IGNORE_CXX_SEEK为防止MPI2协议中一个重复定义问题所使用的选项,为了保证线程安全,必须使用mpi_mt库

对于intel的mpirun,必须在mpirun后加上-env I_MPI_PIN_DOMAIN omp使得每个mpi进程会启动openmp线程。

通过export OMP_NUM_THREADS来控制每个MPI产生多少线程。

OpenMPI 如何实现mult-thread(OpenMP)2

检查编译安装支持mult-thread

1
2
3
shell$ ompi_info | grep "Thread support"
Thread support: posix (MPI_THREAD_MULTIPLE: yes, OPAL support: yes, OMPI progress: no, Event lib: yes)
shell$

“MPI_THREAD_MULTIPLE: yes”说明是支持的。

在C程序里支持mult-thread

1
2
3
4
5
6
7
8
9
10
11
12
#include <mpi.h>
int MPI_Init_thread(int *argc, char ***argv,
int required, int *provided)

argc
C/C++ only: Pointer to the number of arguments.
argv
C/C++ only: Argument vector.
required
Desired level of thread support (integer).
provided
Available level of thread support (integer).

required 可选值 分别是0,1,2,3

1
2
3
4
5
6
7
8
MPI_THREAD_SINGLE
Only one thread will execute.
MPI_THREAD_FUNNELED
If the process is multithreaded, only the thread that called MPI_Init_thread will make MPI calls.
MPI_THREAD_SERIALIZED
If the process is multithreaded, only one thread will make MPI library calls at one time.
MPI_THREAD_MULTIPLE
If the process is multithreaded, multiple threads may call MPI at once with no restrictions.

MPI_Init_thread调用MPI_thread_SINGLE等同于调用MPI_Init。

注意

3.1.6的多线程支持还在初级阶段。开销很高(虽然我不知道为什么)

需要进一步的研究学习

学习MapReduce或者Hadoop? pthread vs openmp?

遇到的问题

暂无

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

参考文献

https://blog.csdn.net/Morizen/article/details/113863591

[2] OpenMPI-multThread

IPCC Preliminary SLIC Optimization 5: MPI + OpenMP

AMD

技术路线 描述 总时间 加速比 备注
Baseline 串行程序 161.7s s 1
more3omp 前面都是可以证明的有效优化 omp_num=32 14.08s
more3omp 前面都是可以证明的有效优化 omp_num=64 11.4s
deletevector 把sz大小的3个vector,移到全局变量,但是需要提前知道sz大小/声明一个特别大的 10.64s 可以看出写成全局变量也不会影响访问时间
enforce_Lscan IPCC opt 4 8.49s 19
enforce_Lscan_MPI_intel intel icpc 3.8s 42.36
Baseline2-max ppm 1.2GB ppm 10*1024*40*1024 928s
enforce_Lscan Baseline2 43.79s 21.2
enforce_Lscan_MPI_intel intel icpc + 双节点两个时间 + MPI(DoRGBtoLABConversion) 18.8s / 20s 46.4
enforce_Lscan_intel intel icpc + 单节点 15.8s 58.74 MPI(DoRGBtoLABConversion)负优化了2s
manualSIMD 13.9s
stream 13.6s
vec2mallocOMP 11.0s
mmap 10.6s
+ -O3 enforce_Lscan_intel 16.2s
+ -xHost 结果不对 17.8s
-Ofast 16.9s
-ipo 15.9s
-O3 -ipo 16.8s
-O3 -march=core-avx2 -fma -ftz -fomit-frame-pointer 16.0s
g++ suggested options -O3 -march-znver1 -mtune=znver1 -fma -mavx2 -m3dnow -fomit-frame-pointer 18.1s
g++ suggested options2 -O3 -march-znver2 -mtune=znver2 -fma -mavx2 -m3dnow -fomit-frame-pointer 19.79s
g++ -Ofast 16.9s
aocc -Ofast 16.3s
aocc suggested options 16.2s

MPI编程

由于是打算两节点两进程MPI,虽然没有OpenMP的共享内存,但是也希望通信能少一点。

PerformSuperpixelSegmentation_VariableSandM

下面关于同步区域的想法是错误的:
因为中心点移动会十分不确定,所以全部同步是最好的。

  1. 第一部分core的思路
    1. 上面numk个中心点直接一分为2,需要同步的是中间相连的$$width*(3S)$$个中心点(由于PerturbSeeds扰动,而且offset比较大,应该是中间相邻的2排,大约3S的高度的区域,上下1.5S高度)。
    2. distlab需要后面覆盖前面的(当然是计算了的区域)。klabels是取distvec更小对应的那个,应该要写个自定义归约。
    3. numk个中心点有奇数行和偶数行,经过思考后是一样的。
  2. 第二部分各中心maxlab的思路(从sz里提取numk个中心的数据)
    1. sz直接一分为2,最小同步的话,就是中间相邻中心点maxlab要max归约。
  3. 第三部分计算sz里的numk个中心点的质心和
    1. 同理,sz直接一分为2,vector相加归约同步

DoRGBtoLABConversion 0.61s

用MPI_Send写,但是一开始没注意是阻塞的,但是为什么这么慢呢?

对比之前的enforce_Lscan 8.49s

  1. DoRGBtoLABConversion 0.56s
  2. PerformSuperpixelSegmentation_VariableSandM 5.52s
    1. core 0.53s
    2. maxlab 0.02s
    3. sigma 0.03s
  3. DetectLabEdges 0.31s
  4. EnforceLabelConnectivity 1.19s
  5. PerformSuperpixelSegmentation_VariableSandM 0.88s

慢了10~20倍猜测:

  1. printf的原因? no 不打印也一样
  2. omp_num的值不对? maybe no
  3. 不在两个节点上? no
  4. g++ mpicxx? no
  5. 没有用IB ? 貌似也不是
  6. openmpi不支持openmp ? 探究方向

好像是openmp没正常运行omp_num的值为 1,32,64时间都一样。感觉是混合编程的编译问题, 而且好像是假Openmp并行,哪里有锁的样子。突然想起来,Quest的混合变成cmake需要打开multthread类似的支持,但是这里并没用。

好像也不是mpi_init_thread的问题

尝试intelmpi

果然有奇效。(结果是对的,后面我没截图了)。看到这里,可能你会觉得这个问题是OpenMPI有地方不支持openmp。但是后面有神奇的事情,如果NODELIST是fa,而不是fb就不能跑,会直接卡住。😰

首先没找到官方手册说明不同,然后研究一下这两个分区的不同。好吧从IB,cpu,内存都没区别。

限制nodelist再跑一遍。

加上打印时间,用fb分区

这个问题又没有了,但是fa分区由于经常跑可能会热一些。

最大的ppm例子

由于时间已经进5s了。所以我们需要更大的例子,再讨论2节点的开销收益,之前的例子是256034000。
这里生成了10240
40960的ppm.再大ppm程序的数组都申请不到栈空间了,需要重新数据结构。

重跑当前最快的enforce_Lscan

icpc + enforce_Lscan_MPI(DoRGBtoLABConversion)

icpc + enforce_Lscan

g++ suggested options

icpc + manualSIMD + lessLscan

icpc + manualSIMD + LscanSimple

icpc + manualSIMD + LscanSimple + stream

icpc + manualSIMD + LscanSimple + stream + mallocOMPinit

icpc + manualSIMD + LscanSimple + stream + mallocOMPinit + mmap

icpc + manualSIMD + LscanSimple + stream + mallocOMPinit + mmap + unrollLoop

放弃的原因

https://www.bilibili.com/video/BV1a44y1q782 58mins-58min50s

需要进一步的研究学习

暂无

遇到的问题

  1. 混合编程写的有问题,双节点不快反慢。怎么写呢?
  2. 那段串行代码真的不能并行吗?
  3. 向量化为什么没有提升呢,是要循环展开吗?

姜师兄建议

  1. MPI非阻塞通信 gather reduce
  2. 手动向量化

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

参考文献