Я отлаживаю приложение, которое работает немного медленнее, когда оно построено как 64-разрядный исполняемый файл ELF Linux, чем как 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 ms.c
Время настенных часов, о котором сообщает time
, больше для сборки -m64
, а Quantify подтверждает, что дополнительное время расходуется на memset
.
До сих пор я тестировал VirtualBox и VMWare (но не Linux для Linux, я понимаю, что мне нужно сделать это дальше). Количество лишнего времени, по-видимому, немного меняется от одной системы к другой.
Что здесь происходит? Есть ли известная проблема, которую мой Google-foo не может раскрыть?
EDIT: Разборка (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
Система:
- CentOS 5.7 2.6.18-274.17.1.el5 x86_64
- GCC 4.1.2
- Intel (R) Core (TM) i7-2600K CPU @3,40 ГГц /VirtualBox
(несоответствие хуже на Xeon E5620 @2,40 ГГц /VMWare )