use*_*068 4 c avx compiler-optimization
我用AVX指令编写了非常简单的程序,但是当我使用-O3选项编译代码和g ++编译器的-O1选项时,我得到的结果不同,这是我的代码:
int main(int argc, char *argv[])
{
int d = 120;
__m256i r = _mm256_set1_epi32(d);
int * p = (int *) &r;
printf("r[0]: %d, ",p[0]);
printf("r[1]: %d, ",p[1]);
printf("r[2]: %d, ",p[2]);
printf("r[3]: %d, ",p[3]);
printf("r[4]: %d, ",p[4]);
printf("r[5]: %d, ",p[5]);
printf("r[6]: %d, ",p[6]);
printf("r[7]: %d \n",p[7]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是我使用这些选项编译时的输出(g ++ test1.c -o test1 -m64 -O3 -ffast-math -march = native -mavx):
r [0]:0,r [1]:0,r [2]:4195520,r [3]:0,r [4]: - 1880829792,r [5]:32767,r [6]:0, r [7]:0
这是我用这些选项编译时的输出(g ++ test1.c -o test1 -m64 -O1 -ffast-math -march = native -mavx):
r [0]:120,r [1]:120,r [2]:120,r [3]:120,r [4]:120,r [5]:120,r [6]:120,r [7]:120
第二个结果(-O1)是正确的,但第一个是错误的.我不知道为什么会这样.
禁用严格别名会降低整个程序的性能!
转换&r为(int*)没有已定义的行为.__m256i r是一个固有的AVX寄存器,不一定映射到内存.通过获取指针,可以强制编译器将其写入内存,并且最终可能会将其映射到int [8]向量.
它可能适用于某些编译器,有些选项,在某些情况下也适用.但是,您不应该在代码中使用它,因为它可能会停止工作而不会发出警告.
"定义行为"的方式是:
int[8] p;
_mm256_storeu_si128((__m256i*)p, r);
printf("r[0]: %d, ",p[0]);
printf("r[1]: %d, ",p[1]);
printf("r[2]: %d, ",p[2]);
printf("r[3]: %d, ",p[3]);
printf("r[4]: %d, ",p[4]);
printf("r[5]: %d, ",p[5]);
printf("r[6]: %d, ",p[6]);
printf("r[7]: %d \n",p[7]);
Run Code Online (Sandbox Code Playgroud)
然后你明确地将寄存器写入内存.这将做同样的事情,但无论编译器选项如何都将始终有效.由于禁用严格别名会降低整体代码优化,因此整个程序运行速度更快.
| 归档时间: |
|
| 查看次数: |
242 次 |
| 最近记录: |