Я отлаживаю приложение, которое работает немного медленнее, когда оно построено как 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));
}
Я строю так:
$ gcc -m32 -std = gnu99 -g -O3 ms.c
и
$ gcc -m64 -std = gnu99 -g -O3 мс.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
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
Система: