- CPU擅长的操作: AES 指令, SHA 指令
- 为了充分利用流水线带来的好处,出现了一种叫做RISC的CPU架构。RISC是Reduced Instruction Set Computer(精简指令集)的缩写
SHA加速
Filecoin系列 - 源码分析 - CPU SHA扩展
- 当前的构造在某些阶段确实涉及SHA哈希,因此具有SHA扩展的CPU将在这些阶段中受益。
- 在 AMD 处理器上看到此优势的主要原因是由于它们执行 SHA 硬件指令
- 看cpu是否支持sha extensions
less /proc/cpuinfo | grep sha_ni
数据并行 SIMD 单指令多数据
单指令多数据( SIMD ) 是Flynn 分类法中的一种并行处理。SIMD 可以是内部的(硬件设计的一部分)并且可以通过指令集架构(ISA) 直接访问,但不应与 ISA 混淆。SIMD 描述了具有多个处理元素的计算机,这些处理元素同时对多个数据点执行相同的操作。
这样的机器利用数据级并行性,但不利用并发性:存在同时(并行)计算,但每个单元在任何给定时刻执行完全相同的指令(只是使用不同的数据)。SIMD 特别适用于常见任务,例如调整数字图像的对比度或调整数字音频的音量。大多数现代CPU设计都包含 SIMD 指令,以提高多媒体使用的性能。
尽量顺序访问数据,矩阵乘法可以很好的印证CPU Cache的作用,再考虑添加-O3 -march=native
开启SIMD自动向量化
SSE 和 SSE2
SSE - Stream SIMD Extentions(流SIMD扩展) 是英特尔提出的即MMX之后新一代(当然是几年前了)CPU指令集,最早应用在PIII系列CPU上。现在已经得到了Intel PIII、P4、Celeon、Xeon、AMD Athlon、duron等系列CPU的支持。另一个原因就是SSE和SSE2的指令系统是非常相似的,SSE2比SSE多的仅是少量的额外浮点处理功能、64位浮点数运算支持和64位整数运算支持。
**SSE为什么会比传统的浮点运算更快呢?**因为它使用了128位的存储单元,这对于32位的浮点数来讲,是可以存下4个的,也就是说,SSE中的所有计算都是一次性针对4个浮点数来完成的,这种批处理当然就会带来效率的提升。我们再来回顾一下SSE的全称:Stream SIMD Extentions(流SIMD扩展)。SIMD就是single instruction multiple data,连起来就是“数据流单指令多数据扩展”,从名字我们就可以更好的理解SSE是如何工作的了。
SSE支持的数据类型是4个32位(共计128位)浮点数集合,就是C、C++语言中的float[4],并且必须是以16位字节边界对齐的, 因此这也给输入和输出带来了不少的麻烦,实际上主要影响SSE发挥性能的就是不停的对数据进行复制以适用应它的数据格式。
//BgiPirServer.cpp//设置 16 个有符号 8 位整数值。
static const block mask = _mm_set_epi8(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);//将压缩的 16 位整数右移 imm8,同时移入符号位,并将结果存储在 dst 中。
expandedS[8 * gIdx + 0] = mask & _mm_srai_epi16(gs[gIdx], 0);
抗cpu并行化的算法
一般可并行化的代码, 软件内启用了多进程或多线程功能.
上下文没有信赖的操作, 编译器可能会做些可并行执行的优化, cpu也可能会做多核间的调度
通过多次迭代BLS12-381的加密算法,即后一个执行的输入信赖前一个执行的输出, 将无法运用多线程或多进程运算, 编译器与cpu也不会作并行化的优化
CPU支持的原子操作
C++11中实现的Atomic类型是通过store
和load
这两个CPU 指令进行数据存取(寄存器和内存之间)的,并且额外接收一个内存序列 (Memory Order)作为参数。C++11支持6种内存排序约束。
Rust的多线程内存模型来源于C++11, 是基于LLVM实现的,所以Rust通过LLVM原子内存排序约束来实现不同级别的原子性。
- 往期精彩回顾:
- 区块链知识系列
- 密码学系列
- 零知识证明系列
- 共识系列
- 公链调研系列
- BTC系列
- 以太坊系列
- EOS系列
- Filecoin系列
- 联盟链系列
- Fabric系列
- 智能合约系列
- Token系列