即将到来的 GCC 5.0 为 x86 带来的新优化

oschina
 oschina
发布于 2014年11月30日
收藏 25

Part1. 加载/存储组的向量化

GCC 5.0 显著的提升了 vector 向量的加载和存储组的代码质量,我这里说的是连续顺序的迭代,例如:

x = a[i], y = a[i + 1], z = a[i + 2] 通过 i 进行迭代,加载了大小为 3 的组

组大小由加载和存储地址的最大和最小值来确定,例如 (i + 2) – (i) + 1 = 3

组中加载和存储的次数小于和等于组的大小,例如:

x = a[i], z = a[I + 2] 通过 i 进行迭代,尽管只有 2 次加载,但是加载组的大小为 3

GCC 4.9 向量组的大小是 2 的指数,而 GCC 5.0 向量化组的大小是 3 ,也可以是 2 的指数,其他的组大小使用比较少。

最常用加载和存储组的场景是结构数组。

  1. 图像转换 (例如将 RGB 结构转为其他)

    (场景测试 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52252)

  2. 多维的坐标 (测试场景 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61403)

  3. 向量的乘法常数矩阵

a[i][0] = 7 * b[i][0] - 3 * b[i][1];
a[i][1] = 2 * b[i][0] + b[i][1];

基本上 GCC 5.0 给我们带来了:

  1. 引入大小为 3 的向量加载和存储组

  2. 改进对原有支持的其他组大小

  3. 通过为特定的 x86 CPU 优化的代码来最大化加载和存储组性能

下面是一个用来比较 GCC 4.9 和 GCC 5.0 性能的一段代码(最大化向量中的元素个数)

int i, j, k; 
byte *in = a, *out = b;
for (i = 0; i < 1024; i++)
{
  for (k = 0; k < STGSIZE; k++)
    {
      byte s = 0;
      for (j = 0; j < LDGSIZE; j++)
        s += in[j] * c[j][k];
      out[k] = s;
    }
  in += LDGSIZE;
  out += STGSIZE;
}

而 "c" 是一个固定的矩阵:

const byte c[8][8] = {1, -1, 1, -1, 1, -1, 1, -1,
                      1, 1, -1, -1, 1, 1, -1, -1,
                      1, 1, 1, 1, -1, -1, -1, -1,
                      -1, 1, -1, 1, -1, 1, -1, 1,
                      -1, -1, 1, 1, -1, -1, 1, 1,
                      -1, -1, -1, -1, 1, 1, 1, 1,
                      -1, -1, -1, 1, 1, 1, -1, 1,
                      1, -1, 1, 1, 1, -1, -1, -1};

在循环中使用简单的计算,例如 add、sub 等操作速度非常快。

  • “in“ 和 “out” 指针指向全局数组 "a[1024 * LDGSIZE]" 和 "b[1024 * STGSIZE]"

  • byte 是一个无符号的 char

  • LDGSIZE 和 STGSIZE – 根据组大小定义加载和存储组的宏

编译选项 "-Ofast" 加 "-march=slm" 用于 Silvermont, "-march=core-avx2" 用于 Haswell 以及所有合并 -DLDGSIZE={1,2,3,4,8} -DSTGSIZE={1,2,3,4,8}

GCC 5.0 到 4.9 (时间上,越大越好)

Silvermont: Intel(R) Atom(TM) CPU  C2750  @ 2.41GHz

性能提升 6.5 倍

Silvermont results

上表结果我们可以看到组大小为 3 的时候结果没那么好。因为当组大小为 3 时在 Slivermont 上需要 8 个 pshufb 指令和大约 5 个 ticks。当然循环依然是向量化的,如果在循环内有更消耗 CPU 的计算,那么效果还是会很不错。(我们再看其他组大小)

Haswell: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz

性能提升 3 倍!

Haswell results

在 Haswell 上组大小为 3 的时候只需 1 个 tick。我们能看到最大的提升就是组大小为 3 的时候。

上述的实验你可以通过下面地址获取相应编译器

GCC 4.9: https://gcc.gnu.org/gcc-4.9

GCC 5.0 trunk built at revision 217914: https://gcc.gnu.org/viewcvs/gcc/trunk/?pathrev=218160

Download matrix.zip

via intel

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
转载请注明:文章转载自 OSCHINA 社区 [http://www.oschina.net]
本文标题:即将到来的 GCC 5.0 为 x86 带来的新优化
加载中

最新评论(10

myicefox
myicefox

引用来自“USIDCBBS”的评论

快过英特尔编译器吗
既然你没说目标平台,那基本上非intel的cpu都是gcc比较快,intel的编译器有意削弱了非自己平台的cpu上的性能。再说,gcc支持的很多平台intel都不支持
poseidon0000
poseidon0000
GCC本来就是通用编译器,支持不同的后端和前端,性能肯定会有一点牺牲的。
冰力
冰力
支持 LLVM 和 GCC,虽然 GCC 代码很乱,但是用起来还是很好用。
emacsen
emacsen
超级点赞
晒太阳的小猪
晒太阳的小猪

引用来自“USIDCBBS”的评论

快过英特尔编译器吗

引用来自“句龙胤”的评论

如果快过Intel的编译器,那Intel就没必要开发了,毕竟只有Intel自己最了解他们的CPU。
那看来有很多东西都是秘密啦。呵呵
hellocc
hellocc
句龙胤
句龙胤

引用来自“USIDCBBS”的评论

快过英特尔编译器吗
如果快过Intel的编译器,那Intel就没必要开发了,毕竟只有Intel自己最了解他们的CPU。
eechen
eechen
Firefox 33.1.1 for Linux 64bit 访问 about:buildconfig 可见其还在使用 GCC 4.7.3 构建。

Linux上使用Qt Creator进行C/C++开发
http://my.oschina.net/eechen/blog/166969
http://dragly.org/wp-content/uploads/2013/03/qt-valgrind.png
clouddyy
clouddyy

引用来自“USIDCBBS”的评论

快过英特尔编译器吗
应该不行吧
USIDCBBS
USIDCBBS
快过英特尔编译器吗
返回顶部
顶部