编译优化之 - 向量化优化入门

2023-11-18

1. 介绍
2. Intel高级向量扩展
3. GCC中向量化
4. ICC中向量化
5. AOCC/LLVM中向量化

1. 介绍

什么是自动向量化?

  自动向量化(automatic vectorization)是自动并行化(automatic parallelization)的一种特殊情况,它将一次处理一对的标量运算转换为一次并行处理多对的向量运算。因此向量化可以显着加速一些带循环的程序运算,尤其是在大型数据集上。根据arch信息,编译器优化的目标可以是Intel或AMD处理器中的SSE*、AVX/AVX2或更高级的指令,或ARM处理器中的NEON指令。
  默认情况下,GCC、ICC或AOCC/LLVM编译器中都启用了部分自动向量化功能。这些指令受运行时检查保护,即运行时检查机器是否支持该指令集,如果不支持则使用其它的指令集。

什么是SIMD指令?

  SIMD(Single instruction, multiple data)单指令多数据技术能对程序中数据进行并行处理,提高吞吐量。它将原来需要多次装载的数据一次性装载到向量寄存器,即SIMD指令允许在一个步骤中处理多个数据。现代的CPU设计都包括SIMD指令,以提高多媒体程序和科学计算程序的性能,但SIMD与利用线程的SIMT不同。SIMD指令的首次使用是在1966年,它一般分为两种:

  • 手工向量化:通过内嵌汇编码或编译器提供的内函数来添加SIMD指令。
  • 自动向量化:利用编译器分析串行程序中控制流和数据流的特征,识别程序中可以向量执行的部分,将标量语句自动转换为相应的SIMD向量语句。
机器支持哪些指令集?
cat /proc/cpuinfo

本机cpu支持的simd指令集如下:
cpu

gcc -c -Q -march=native --help=target

本机GCC8.2支持的simd指令集如下:
gcc

注意:向量化的操作需要机器硬件的支持!


2. Intel高级向量扩展

较早的相关英特尔SSE指令还支持各种有符号和无符号整数大小,包括有符号和无符号byte(B,8位),word(W,16位),doubleword(DW,32位),quadword( QW(64位)和doublequadword(DQ,128位)长度。

表1:英特尔AVX后缀标记

标记 含义
[s / d] 单精度或双精度浮点
[ps / pd / sd] 打包单精度、打包双精度、标量双精度
[i / u] nnn 位大小为nnn的有符号或无符号整数,其中nnn是128、64、32、16或8
epi32 扩展打包的32位有符号整数
si256 标量256位整数

更多关于Intel Advanced Vector Extensions的信息请见:Introduction to Intel® Advanced Vector Extensions

  1. MMX指令
    MultiMedia eXtensions(MMX),MMX指令主要使用的寄存器为MM0 ~ MM7,与浮点运算不能同时进行。MMX指令能一次性地操作1个64-bit的数据、或者两个32-bit的数据、或者4个16-bit的数据、或者8个8-bit的数据。
    MMX指令集的扩展包括:3DNow!、SSE、AVX

  2. SSE指令
    Streaming SIMD eXtensions(SSE),SSE指令采用了独立的寄存器组XMM0 ~ XMM7,64位模式下为XMM0 ~ XMM15,并且这些寄存器的长度也增加到了128-bit。
    SSE指令的升级版包括:SSE2/SSE3/SSSE3/SSE4

  3. AVX/AVX2指令
    Advanced Vector eXtentions(AVX),AVX对XMM寄存器做了扩展,从原来的128-bit扩展到了256-bit,并从XMM0–XMM7重命名为YMM0–YMM7,仍可通过SSE指令对YMM寄存器的低128位进行操作。新指令使用英特尔所谓的VEX前缀进行编码,这是一个两字节或三字节的前缀,旨在消除当前和将来的x86/x64指令编码的复杂性。AVX2将大多数整数命令扩展为256位,并引入了融合的乘加(FMA)操作。

  4. FMA指令
    Fused-Multiply-Add(FMA),FMA指令集是128-bit和256-bit的SSE的扩展指令集,以进行乘加运算。共有两种变体:FMA4、FMA3,自2014年以来,从PILEDRIVER架构开始,AMD处理器就支持FMA3;从Haswell处理器和Broadwell处理器开始,英特尔则支持FMA3。

  5. AVX512*指令
    英特尔架构处理器支持旧式和现代指令集,从64位MMX扩展到新的512位指令AVX-512。ZMM的低256-bit与YMM混用。ZMM的前缀为EVEX。与AVX / AVX2相比,AVX-512最显着的新功能是512位矢量寄存器宽度。

  6. 其他指令
    KNC等其他指令集。

Intel不同架构向量化指令集如下:

intel

表2: 部分FMA指令说明

指令 含义
VFMADD[z][P/S][D/S] 乘法加法融合指令:A = r1 * r2 + r3(packed/scalar of double/single)
VFMSUB[z][P/S][D/S] 乘法减法融合指令:A = r1 * r2-r3(packed/scalar double/single)
VFNMADD[z][P/S][D/S] 乘法加法融合的负指令:A = -r1 * r2+r3( packed/scalar double/single)
VFNMSUB[z][P/S][D/S] 乘法减法融合的负指令: A = -r1 * r2-r3(packed/scalar double/single)
VFMADDSUB[z]P[D/S] 乘法与加减法交替的融合指令,奇数索引:A = r1 * r2 + r3,偶数索引:A = r1 * r2-r3(packed double/single)
VFMSUBADD[z]P[D/S] 乘法与加减法交替的融合指令,奇数索引:A = r1 * r2-r3 ,偶数索引:A = r1 * r2+r3(packed double/single)

其中[z]代表字符串132或213或231,对应操作数A,B,C的使用顺序:

  • 132是A = AC + B
  • 213是A = AB + C
  • 231是A = BC + A

3. GCC中向量化

GCC8.2.0中关于向量化操作的选项有:-ftree-loop-vectorize、-ftree-slp-vectorize、-ftree-loop-if-convert、-ftree-vectorize、-fvect-cost-model=model、-fsimd-cost-model=model。前两个向量化选项默认情况下在-O3中已启用,这里不一一说明。

具体每个选项的使用及详细介绍请见:https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Optimize-Options.html#Optimize-Options

3.1 示例

使用的示例代码如下:

// vect.c
int main()
{
  int N = 1000;
  int a[N], b[N], c[N];
  for (int i = 0; i < N; i++) {
    b[i]=c[i]=i;
    a[i] = b[i] + c[i];
  }

  for (int i = 0; i < N; i++) {
   a[i] = a[i] + a[i];
  }

   printf("%d\n",a[100]);
   return 0;
}

如何知道一个循环是否启用了向量化?  gcc中可使用-fopt-info-vec-optimized-fopt-info-vec命令来查看,操作如下:
gcc1
或使用-fopt-info-vec-all选项记录下所有信息,并保存到一个文件,方便查看,如下所示:
gcc2
GCC中向量化操作功能有较多限制,比如:

  • 循环中有较多条件语句,函数调用等,复杂的cfg。这样做不了向量化优化
  • 嵌套循环中,外层循环的索引参与内部循环计算,导致无法向量化优化
  • 其他一些特性

假若想显式的指定gcc采用什么向量化进行编译(前提是硬件支持),可参考如下操作:

gcc -O3 -march=core-avx2 vect.c -std=c99 -S -o vect.s

使用-march=core-avx2指令指定采用AVX2指令集(可指定其他指令集)。部分汇编码如下:
gcc3


4. ICC中向量化

Intel编译器中可用一下几种方式生成向量化指令:

  • SIMD vector intrinsics
  • OpenMP* 4.0 (SIMD part)
  • Auto-vectorization
  • Inline assembly code

英特尔MIC架构向量化的最重要方面之一是数据对齐。例如向量加法操作,如果编译器不知道数据对齐方式(通常是这种情况是对齐方式不正确),则将迫使编译器生成效率较低的代码。因此,重要的是优化数据的对齐并适当地将信息传达给编译器。

更多关于循环矢量化优化程序的信息请见:https://software.intel.com/en-us/articles/program-optimization-through-loop-vectorization

4.1 示例

在此使用的icc18,和测试代码如下:

// tmp.c
#include<stdio.h>
int main()
{
   int n = 1000;
   int a[n],b[n];
   for (int i = 0; i < n; ++i)
        {
           a[i] = i * 10;
           b[i] = a[i]+i * 10;
        }
    printf("%d\n",b[10]);
    return 0;
}

如何知道一个循环是否启用了向量化?  icc中可使用-qopt-report -qopt-report-phase=vec命令查看,操作如下:

icc -qopt-report -qopt-report-phase=vec -O3 tmp.c -std=c99

// icc: remark #10397: optimization reports are generated in *.optrpt files in the output location

vim tmp.optrpt

// 报告结果如下
Intel(R) Advisor can now assist with vectorization and show optimization
  report messages with your source code.
See "https://software.intel.com/en-us/intel-advisor-xe" for details.


Begin optimization report for: main()

    Report from: Vector optimizations [vec]


LOOP BEGIN at tmp.c(6,4)
   remark #15300: LOOP WAS VECTORIZED
LOOP END

LOOP BEGIN at tmp.c(6,4)
<Remainder loop for vectorization>
   remark #15301: REMAINDER LOOP WAS VECTORIZED
LOOP END
===========================================================================

如上remark #15301: REMAINDER LOOP WAS VECTORIZED所示,icc对该代码启用了循环优化,部分汇编码如下所示:
icc1
如果要求编译器不要向量化特定循环,可以使用#pragma novector命令,如下:

#pragma novector 
for (int i = 0; i < n; ++i)

//同样使用以上操作,生成报告如下
LOOP BEGIN at tmp.c(7,4)
   remark #15319: loop was not vectorized: novector directive used
LOOP END
===========================================================================

部分汇编码如下所示:
icc2

类似命令还有:

  • #pragma vector always
  • #pragma vector align

假若想显式的指定icc采用什么向量化进行编译(前提是硬件支持),可参考如下操作:

icc -qopt-report -qopt-report-phase=vec -O3 -march=core-avx2 tmp.c -S -o tmp0.s -std=c99

使用-march=core-avx2指令指定采用AVX2指令集(可指定其他指令集),-qopt-report -qopt-report-phase=vec记录向量化信息。部分汇编码如下:
icc3


5. AOCC/LLVM中向量化

  LLVM有两种向量化:作用于循环的Loop Vectorizer、将代码中找到的多个标量合并为矢量的SLP Vectorizer。默认情况下已启用了两种向量化优化。
  AOCC2.1中向量化相关的选项有:-enable-strided-vectorization、-enable-epilog-vectorization、-vectorize-memory-aggressively、-global-vectorize-slp、-region-vectorize、-suppress-fmas。

具体每个选项的使用及详细介绍请见:https://developer.amd.com/wp-content/resources/AOCC-2.1-Clang-the%20C%20C++%20Compiler.pdf

5.1 示例

LLVM中若想禁用Loop Vectorizer和SLP Vectorizer,可以使用命令行标志通过clang禁用它:

clang ... -fno-vectorize  ohter.c
clang ··· -fno-slp-vectorize file.c

可以使用命令行标志“ -force-vector-width”来控制矢量化SIMD宽度:

clang  -mllvm -force-vector-width=8 ...
opt -loop-vectorize -force-vector-width=8 ...

可以使用命令行标志“ -force-vector-interleave”来控制展开因子:

clang  -mllvm -force-vector-interleave=2 ...
opt -loop-vectorize -force-vector-interleave=2 ...

以上示例及说明参考自“Auto-Vectorization in LLVM”,更多详细信息请见:https://llvm.org/docs/Vectorizers.html

在此使用以下示例代码:

// tmp.c
#include<stdio.h>
int main()
{
    int n = 1000;
    int a[n],b[n];
   for (int i = 0; i < n; ++i)
   {
        a[i] = i * 2;
        for(int j = 0; j<n/2;j++)
        {
           b[i] = a[i]+a[j]*2;
        }
   }
   printf("%d\n",b[10]);
   return 0;
}

如何知道一个循环是否启用了向量化?  llvm中可使用-Rpass-missed=loop-vectorize命令查看,操作如下:

clang -O3 -Rpass-missed=loop-vectorize tmp.c

// 得到信息如下。可知对于如上循环很多编译器是做不了向量化优化的
tmp.c:6:4: remark: loop not vectorized [-Rpass-missed=loop-vectorize]
   for (int i = 0; i < n; ++i)
   ^

假如使用一下代码:

#include<stdio.h>
int main()
{
   int n = 1000;
   int a[n],b[n];
   for (int i = 0; i < n; ++i)
   {
       a[i] = i * 2;
   }
   printf("%d\n",a[10]);
   return 0;
}

再使用clang -O3 -Rpass=loop-vectorize tmp.c命令查看,便得到一下结果:

tmp.c:6:4: remark: vectorized loop (vectorization width: 4, interleaved count: 2) [-Rpass=loop-vectorize]
   for (int i = 0; i < n; ++i)
   ^

对于以上代码,AOCC2.1使用-Wl,-mllvm -Wl,-region-vectorize命令操作如下:

clang -O3 -Rpass=loop-vectorize tmp.c -flto -Wl,-mllvm -Wl,-region-vectorize

AOCC2.1中向量化操作与LLVM基本相似,在此不做更多介绍。


References:
  • SIMD自动向量化编译优化概述
  • https://colfaxresearch.com/skl-avx512/
  • https://en.wikipedia.org/wiki/Advanced_Vector_Extensions
  • https://llvm.org/docs/Vectorizers.html
  • https://developer.amd.com/wp-content/resources/AOCC-2.1-Clang-the%20C%20C++%20Compiler.pdf
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编译优化之 - 向量化优化入门 的相关文章

  • 龙书学习笔记

    目录 第一章 引论 1 1 语言处理器 1 2 一个编译器的结构 1 2 1 词法分析 1 2 2 语法分析 1 2 3 语义分析器 1 2 4 中间代码生成
  • C语言解释器的实现--序(零)

    在写CuteC文本编辑器的同时 为了使之有脚本执行能力 特意实现了一个简易的C语言解释器 所谓的解释器 就是它是解析执行脚本文件的 并不产生可执行的目标代码 它具备了C语言的几乎全部的语法 随着时间的推移 我打算把它作为一个独立的项目来开发
  • 编译器与平台相关性

    每种处理器都可能会有自己的汇编语言编译器 而对于同一款处理器来说 针对不同的平台 比如 Windows 和 Linux 也会有不同版本的汇编语言编译器 理论上 不管用的是什么操作系统 Windows 也好 DOS 也好 Linux 也好 只
  • 条件编译小结

    编码的时候经常要用到条件编译 每次都到网上去查比较浪费时间 今天总结一下以备后用 编译器 GCC ifdef GNUC if GNUC gt 3 GCC3 0以上 Visual C ifdef MSC VER 非VC编译器很多地方也有定义
  • 【C++基础学习】引起类模板被实例化情形总结

    在我们使用类模板时 只有当代码中使用了类模板的一个实例的名字 而且上下文环境要求必须存在类的定义时 这个类模板才被实例化 并不是每次使用一个类都要求知道该类的定义 1 声明一个类模板的指针和引用 不会引起类模板的实例化 因为没有必要知道该类
  • printf标识总结(转)

    printf标识总结 转 Dev C 下基本数据类型学习小结 环境 Dev C 4 9 6 0 gcc mingw32 使用 Wall编译选项 基本类型包括字节型 char 整型 int 和浮点型 float double 定义基本类型变量
  • crmeb 前端源码uniapp编译成微信小程序上传开发工具教程

    1 下载登录微信开发工具 下载地址 https developers weixin qq com miniprogram dev devtools download html 推荐使用稳定版 安装完成后后 打开 微信扫码登陆 2 下载HBu
  • 指针以及内存分配

    1 指针很灵活 这使得指针很难管理 在定义指针时 将在栈中开辟一块内存存放指针的地址 栈内的内存由系统分配和释放 指针的地址内存只是存放指针的地址 不存放指针指向的数据 值得注意的是 定义指针时指针会随机指向一块内存 如int p p会指向
  • 【Java虚拟机】第三章、jvm运行期优化,解释器,编译器(AOT静态编译,JIT动态编译)

    已经第三章了 看了前两章是不是有点懵 或者开始意识到了什么 或者整个串联起来了 回顾一下 第一张主要讲的是jvm怎么创建 第二章讲的是jvm内存结构 和番外篇class加载过程 那么我们再结合这一章解释器和编译器 静态和动态编译 把他们串到
  • c++ 常见编译错误

    1 redefinition of class previous definition of class 表示重复定义了类 一般说来是因为在你进行该类定义的头文件中没有使用 ifndef define和 endif来进行保护 如果你确定你在
  • 多核编程学习笔记之OpenMP(一)

    多核编程学习笔记之OpenMP 一 I 配置及简介 1 1 在VC 2008 VC9 0 中 如果没有任何设置 在代码中使用编译指导语句将不会报错 但是也不起作用 1 2 OpenMP发展与优势 1 2 1 OpemMP的规范由SGI发起
  • 在 Ubuntu 操作中安装Code::Blocks

    在 Ubuntu 操作 中安装Code Blocks 步骤如下 安装步骤 1 先把编译环境 C库 C 库和Boost库装好 如下 sudoapt get install build essential 有可能安装 build essenti
  • MATLAB下配置C和C++编译器(MinGW)

    很多时候需要在Matlab下使用C或C 边写的代码 这时候就需要先用编译器将代码编译成Matlab可以用的mex文件 检测Matlab有没有可以使用的编译器 可以在命令行窗口下 输入mex setup 如果有的话就会显示出可以用的编译器 无
  • Ubuntu18.04 编译安装llvm-clang

    背景知识 LLVM和GCC的区别 传统编译器 传统编译器的工作原理基本上都是三段式的 可以分为前端 Frontend 优化器 Optimizer 后端 Backend 前端负责解析源代码 检查语法错误 并将其翻译为抽象的语法树 Abstra
  • linux下c/c++开发工具集

    clang llvm组合 lldb debugger 代码补全vim clang complete linux开发花环境 vim eclipse kscope kate kdevelop emacs win虚拟机 source insigh
  • vscode运行cpp文件:检测到 #include 错误。请更新 includePath。已为此翻译单元(E:\C++ Code\test1\test1\test1.cpp)禁用波形曲线。

    刚为vscode配置好C 编译环境准备刷leetcode 结果写cpp文件时发现 include头文件总是报错 我就很迷惑了 include
  • dynamic_cast报错 异常

    转载请标明是引用于 http blog csdn net chenyujing1234 代码 http www rayfile com zh cn files 89459c23 7a0b 11e1 908f 0015c55db73d UnH
  • 为什么栈的数组长度必须是一个常量?而堆的数组长度可以是变量。为什么栈的大小有限制?

    为什么栈的数组长度必须是一个常量 而堆的数组长度可以是变量 栈区数组长度使用变量会报错 其原因就在于栈是编译器管理的 在程序运行前就已经分配好了空间的大小 而使用变量 编译器无法知道该分配多大的内存空间 于是报错 但堆上的内存是动态创建的
  • 使用嵌入式linux完全手册光盘的arm-linux-gcc 遇到问题 自己编译

    Redhat9下重新生成交叉编译器gcc 3 4 5 glibc 2 3 6 看到论坛上有兄弟也遇到 arm linux gcc lib tls libc so 6 version GLIBC 2 4 not found required
  • make: *** No rule to make target 错误原因、分析和解决办法

    问题描述 在用codewarrior编译的时候 遇到编译器报如下错误 mingw32 make No rule to make target D CW Workspace Renalt PBG BOOT Project Settings L

随机推荐

  • [Qt3d] 导出QtEntity为Obj格式(遍历QtEntity)

    原文链接 https www yuque com softdev qt txv1lx class Qui3DView private struct date struct QPointer
  • java.awt.Color类

    Color类概述 Color是用来封装颜色的 支持多种颜色空间 默认为RGB颜色空间 每个Color对象都有一个alpha通道 值为0到255 代表透明度 当alpha通道值为255时 表示完全不透明 当alpha通道值为0时 表示完全透明
  • Cordova环境搭建/win10下必备依赖环境配置(Android开发)

    Cordova环境依赖 1 win10系统 2 Java环境 3 Node环境 4 AndroidStudio 5 Ant 6 Gradle 安装node环境 1 使用node官网网址下载node包 最好使用稳定版本 https nodej
  • 从C过渡到C ++的3个理由

    几十年来 嵌入式软件工程师之间一直在争论他们应该使用C还是C 根据2020年嵌入式市场调查 在大多数情况下 微控制器制造商提供的软件都以C语言提供 实际上 有56 的嵌入式软件是用C语言编写的 但是 C 逐渐流行起来 大约23 的新嵌入式软
  • Java面向对象编程

    主机甲和乙已建立了TCP连接 甲始终以MSS 1KB大小的段发送数据 并一直有数据发送 乙每收到一个数据段都会发出一个接收窗口为10KB的确认段 若甲在t时刻发生超时时拥塞窗口为8KB 则从t时刻起 不再发生超时的情况下 经过10个RTT后
  • Ubuntu安装git

    使用 apt get install git 安装git 报错 这个错误信息通常表示您的系统上没有可用的 git 软件包 这可能是因为您的软件源列表中没有包含 git 软件包所在的软件源 或者您的软件源列表已经过期 解决 如果您使用的是 U
  • RuntimeError: Attempting to deserialize object on CUDA device 1 but torch.cuda.device_count() is 1.

    成功解决 RuntimeError Attempting to deserialize object on CUDA device 1 but torch cuda device count is 1 报错内容 程序在这一步报错 check
  • Android kotlin自定义自动换行LinearLayout

    目录 1 概述 2 实现步骤 3 kotlin自定义自动换行LinearLayout核心代码实现功能 3 1自定义LinearLayout
  • spring快速入门

    1 导入坐标
  • stack容器

    stack容器 1 stack 基本概念 概念 stack是一种先进后出 First In Last Out FILO 的数据结构 它只有一个出口 栈中只有顶端的元素才可以被外界使用 因此栈不允许有遍历行为 栈中进入数据称为 入栈 push
  • dll load failed: 找不到指定的模块_【已解决】“由于找不到xinput1_3.dll,无法继续执行代码”...

    许多小伙伴在玩游戏或者使用电脑的过程中 电脑突然提示 由于找不到xinput1 3 dll 无法继续执行代码 导致游戏等程序无法正常启动运行 并且导致电脑系统弹窗报错 那xinput1 3 dll丢失怎么修复呢 下面让小编手把手教你解决方法
  • CentOS7安装OpenStack(Liberty)

    1 安装yum源 yum install https buildlogs centos org centos 7 cloud x86 64 openstack liberty centos release openstack liberty
  • 百度智能云千帆大模型三连击:接入LLaMA2等33个模型、上线插件功能和103个Prompt模板

    作为全球首个一站式企业级大模型平台 百度智能云 千帆大模型平台 在提供包括文心一言在内的大模型服务及第三方大模型服务的同时 还提供大模型开发和应用的整套工具链 帮助企业解决大模型从训练到开发过程中的全链条问题 自2023年3月发布以来 千帆
  • 看懂android中的adapter适配器

    首先需要知道一共有4个文件 fragment类 adapter fragment的布局文件 adapter中的item的布局文件 1 首先声明一个控件 RecyclerView 2 然后声明一个adapter类 3 在initView 上
  • python中typeerror_详解python中的TypeError错误解决办法

    新手在学习python时候 会遇到很多的坑 下面来具体说说其中一个 在使用python编写面向对象的程序时 新手可能遇到TypeError this constructor takes no arguments这个错误 例如下面的程序 cl
  • gtest 单元测试工具的基本使用

    gtest 单元测试 gtest 简介 gtest 优点 安装 gtest 测试 demo 总结 gtest 简介 gtest是Google的一套用于编写C 测试的框架 可以运行在很多平台上 包括Linux Mac OS X Windows
  • 获取时间和脸颊、下颚线灯模式

    电流检测的应用 电路检测电路常用于 高压短路保护 电机控制 DC DC换流器 系统功耗管理 二次电池的电流管理 蓄电池管理等电流检测等场景 对于大部分应用 都是通过感测电阻两端的压降测量电流 一般使用电流通过时的压降为数十mV 数百mV的电
  • android动画内存优化,Android 性能优化之内存优化

    定义 内存泄漏 Memory Leak 指 程序在申请内存后 当该内存不需再使用但却无法被释放的现象 内存溢出 OOM 应用程序所需的内存超出了为其分配的内存限额 Android将进程分为5个优先等级 前台进程 可见进程 服务进程 后台进程
  • google.api.http

    Http 定义api服务的http配置 它包含一个httprule列表 每个列表指定一个rpc方法到一个或多个http rest api方法的映射 字段 描述 rules HttpRule 一个适用于各个API方法的http配置规则列表 注
  • 编译优化之 - 向量化优化入门

    1 介绍 2 Intel高级向量扩展 3 GCC中向量化 4 ICC中向量化 5 AOCC LLVM中向量化 1 介绍 什么是自动向量化 自动向量化 automatic vectorization 是自动并行化 automatic para