Dav*_*ron 12 c linux performance 32bit-64bit
我正在调试一个运行速度相当慢的应用程序,当构建为64位Linux ELF可执行文件而不是32位Linux ELF可执行文件时.使用Rational(IBM)Quantify,我跟踪了很多性能差异(鼓声......)memset.奇怪的是,memset正在采取很多在64位可执行更长的时间.
我甚至可以通过一个简单的小应用程序看到这个:
#include <stdlib.h>
#include <string.h>
#define BUFFER_LENGTH 8000000
int main()
{
unsigned char* buffer = malloc(BUFFER_LENGTH * sizeof(unsigned char));
for(int i = 0; i < 10000; i++)
memset(buffer, 0, BUFFER_LENGTH * sizeof(unsigned char));
}
Run Code Online (Sandbox Code Playgroud)
我这样建造:
$ gcc -m32 -std=gnu99 -g -O3 ms.c
和
$ gcc -m64 -std=gnu99 -g -O3 ms.c
所报告的挂钟时间time对于-m64构建而言更长,而Quantify确认了额外的时间用于memset.
到目前为止,我已经在VirtualBox和VMWare中进行了测试(但不是裸机Linux;我意识到我需要在下一步做到这一点).从一个系统到另一个系统,花费的额外时间似乎有所不同.
这里发生了什么?是否存在我的Google-foo无法发现的众所周知的问题?
编辑:gcc ... -S我的系统上的反汇编()显示memset正在作为外部函数调用:
32位:
.LBB2:
.loc 1 14 0
movl $8000000, 8(%esp)
.loc 1 12 0
addl $1, %ebx
.loc 1 14 0
movl $0, 4(%esp)
movl %esi, (%esp)
call memset
Run Code Online (Sandbox Code Playgroud)
64位:
.LBB2:
.loc 1 14 0
xorl %esi, %esi
movl $8000000, %edx
movq %rbp, %rdi
.LVL1:
.loc 1 12 0
addl $1, %ebx
.loc 1 14 0
call memset
Run Code Online (Sandbox Code Playgroud)
系统:
编译示例代码时,编译器会看到固定的块大小(~8MB)并决定使用库版本。尝试编写更小的块的代码(仅用于 memset 几个字节) - 比较反汇编。
虽然我不知道为什么 x64 版本较慢。我猜你的时间测量代码有问题。
块移动(memcpy)和块集(memset)的代码生成被重写。GCC 现在可以根据要复制的块的大小和要优化的 CPU 选择最佳算法(循环、展开循环、带有rep 前缀的指令或库调用)。添加了新选项 -minline-stringops-dynamically。使用此选项,未知大小的字符串操作将被扩展,以便通过内联代码复制小块,而对于大块,则使用库调用。当库实现能够使用缓存层次结构提示时,这会产生比 -minline-all-stringops 更快的代码。可以通过 -mstringop-strategy 覆盖选择特定算法的启发式。新近还内联了非 0 值的 memset。
希望这可以解释编译器设计者尝试做的事情(即使这是针对另一个版本);-)
| 归档时间: |
|
| 查看次数: |
2123 次 |
| 最近记录: |