gcc - 用于堆栈与堆访问的 gcc 程序集
问题描述
这里有两个指向 Godblot 的链接(由实际代码替换),在一种情况下,我将在堆栈上声明的数组的元素相加,第二个和在堆上分配的数组的元素相加(请忽略 malloc 的不正确大小)。
堆(-std=c++17 -O3 -mavx2):
#include <stdio.h>
#include <stdlib.h>
int access(){
int sum;
//int vec[10000];
int *vec = (int*)malloc(10000*sizeof(int));
for(int i=0;i<10000;i++)
sum+=vec[i];
return sum;
}
堆组装:
access():
push rbp
mov edi, 10000
mov rbp, rsp
and rsp, -32
call malloc
vpxor xmm1, xmm1, xmm1
lea rdx, [rax+40000]
.L2:
vmovdqu xmm2, XMMWORD PTR [rax]
vinserti128 ymm0, ymm2, XMMWORD PTR [rax+16], 0x1
add rax, 32
vpaddd ymm1, ymm1, ymm0
cmp rdx, rax
jne .L2
vmovdqa xmm0, xmm1
vextracti128 xmm1, ymm1, 0x1
vpaddd xmm1, xmm0, xmm1
vpsrldq xmm0, xmm1, 8
vpaddd xmm0, xmm1, xmm0
vpsrldq xmm1, xmm0, 4
vpaddd xmm0, xmm0, xmm1
vmovd eax, xmm0
vzeroupper
leave
ret
对于堆栈 C 代码,只需使用在先前 C 代码中注释的堆栈上声明的 vec。
Stack() 汇编代码:
access():
push rbp
vpxor xmm0, xmm0, xmm0
mov rbp, rsp
and rsp, -32
sub rsp, 39880
lea rax, [rsp-120]
lea rdx, [rsp+39880]
.L2:
vpaddd ymm0, ymm0, YMMWORD PTR [rax]
add rax, 32
cmp rdx, rax
jne .L2
vmovdqa xmm1, xmm0
vextracti128 xmm0, ymm0, 0x1
vpaddd xmm0, xmm1, xmm0
vpsrldq xmm1, xmm0, 8
vpaddd xmm0, xmm0, xmm1
vpsrldq xmm1, xmm0, 4
vpaddd xmm0, xmm0, xmm1
vmovd eax, xmm0
vzeroupper
leave
ret
知道为什么在堆情况下它需要使用更多指令。它似乎也跳过了存储在 xmm2 寄存器中的 16 个字节的数据?
如果我们将编译器参数从 -mavx2 更改为 -mavx512f 或 remove 完全删除它,代码看起来相似。gcc 中继版本有问题吗?
Clang 似乎展开了循环并生成了有意义的代码。
解决方案
推荐阅读
- python - 十六进制字符串到可用的十六进制字节()
- rest - 最佳实践:Restful 事件驱动微服务架构中的往返调用
- bash - 在这种情况下如何申请一段时间?
- python - 如何使用嵌套字典查询 Django JSONField?
- docker - 如果工作空间处于停止状态,Che 6 工作空间不会显示为退出的 docker 容器
- javascript - 如果 div 中没有内容,则隐藏导航链接
- java - Eclipse:“用分支、标签或版本替换”不能按预期工作
- python - 无法从函数返回和分配变量?
- flutter - 如何在颤振中创建下拉选项卡
- laravel - 如何使用 maatawebsite/excel 3.1 版获取下拉列表中的数据