相关疑难解决方法(0)

如何让GCC完全展开这个循环(即剥离这个循环)?

有没有一种方法来指示GCC(版本我用4.8.4),以展开在底层函数while循环完全,即剥离这个循环?循环的迭代次数在编译时是已知的:58.

我先解释一下我的尝试.

通过检查GAS输出:

gcc -fpic -O2 -S GEPDOT.c
Run Code Online (Sandbox Code Playgroud)

使用12个寄存器XMM0 - XMM11.如果我将标志-funroll-loops传递给gcc:

gcc -fpic -O2 -funroll-loops -S GEPDOT.c
Run Code Online (Sandbox Code Playgroud)

循环只展开两次.我检查了GCC优化选项.GCC表示-funroll-loops也会打开-frename-registers,所以当GCC展开一个循环时,它先前选择的寄存器分配是使用"遗留"寄存器.但是XMM12只剩下4个 - XMM15,所以GCC最多只能展开2次.如果有48个而不是16个XMM寄存器可供使用,GCC将毫无困难地展开while循环4次.

然而,我做了另一个实验.我首先手动两次展开while循环,获得一个函数GEPDOT_2.然后两者之间没有任何区别

gcc -fpic -O2 -S GEPDOT_2.c
Run Code Online (Sandbox Code Playgroud)

gcc -fpic -O2 -funroll-loops -S GEPDOT_2.c
Run Code Online (Sandbox Code Playgroud)

由于GEPDOT_2已用完所有寄存器,因此不执行展开.

GCC确实注册了重命名,以避免引入潜在的错误依赖.但我确信在我的GEPDOT中没有这样的潜力; 即使有,也不重要.我尝试自己展开循环,展开4次比展开2次更快,比没有展开更快.当然我可以手动展开更多次,但这很乏味.GCC可以帮我吗?谢谢.

// C file "GEPDOT.c"
#include <emmintrin.h>

void GEPDOT (double *A, double *B, double *C) {
  __m128d A1_vec = _mm_load_pd(A); A += 2;
  __m128d B_vec = _mm_load1_pd(B); B++;
  __m128d C1_vec = A1_vec * B_vec; …
Run Code Online (Sandbox Code Playgroud)

c x86 gcc hpc loop-unrolling

9
推荐指数
1
解决办法
4149
查看次数

标签 统计

c ×1

gcc ×1

hpc ×1

loop-unrolling ×1

x86 ×1