32vs64

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

32vs64

Сообщение xdsl » 26.12.2013 08:57:20

Пишу тут пособие по freepascal и обнаружил интересный факт: 32-битные приложения выполняют арифметические операции с 8-16-32-битными значениями раза в полтора быстрее, чем 64-битные. Проверял, естественно, на 64-битных процессорах, а именно: Intel(R) Core(TM) i5-2520M, Intel(R) Xeon(R) CPU E5620 @ 2.40GHz, Dual-Core AMD Opteron(tm) Processor 8216, Dual-Core AMD Opteron(tm) Processor 2218. Использованные оси - WinXP 32bit, Win7 64bit, AltLinux p7 32bit, AltLinux p7 64bit. Цель была показать, что применять типы qword и int64 в 32-битных системах крайне неэффективно. Цель была достигнута, но побочно обнаружился собственно сабж.

Программа вида:
Код: Выделить всё
{$mode objfpc}
uses sysutils,dateutils;
const MAX=200000000;
{$IFDEF CPU64} BITS=64; {$ENDIF}
{$IFDEF CPU32} BITS=32; {$ENDIF}
{$IFDEF CPU16} BITS=16; {$ENDIF}
var
     i32,MulDiv32:longint;
     i64,MulDiv64:int64;
     dt:tdatetime;
begin
dt:=now();
i32:=1; MulDiv32:=10;
while i32<MAX do i32:=(((i32+2)*MulDiv32) div MulDiv32)-1;
writeln(millisecondsbetween(now(),dt),' мс: 32-битная арифметика для ',BITS,'-разрядной ОС');

dt:=now();
i64:=1; MulDiv64:=10;
while i64<MAX do i64:=(((i64+2)*MulDiv64) div MulDiv64)-1;
writeln(millisecondsbetween(now(),dt),' мс: 64-битная арифметика для ',BITS,'-разрядной ОС');
end.


После компиляции в 64 бита и запуска получаем примерно следующее:
3620 мс: 32-битная арифметика для 64-разрядной ОС
3634 мс: 64-битная арифметика для 64-разрядной ОС


После компиляции в 32 бита и запуска получаем более интересный результат:
2296 мс: 32-битная арифметика для 32-разрядной ОС
7932 мс: 64-битная арифметика для 32-разрядной ОС


Результаты от запуска к запуску колеблются в пределах 5%, так-что на общую картину это не влияет.
Переписал на чистом Си, заменив longint на long, int64 на long long и получил для первой строки аналогичные результаты. Вторая строка, кстати, показала, что Си с 64-битными значениями работает одинаково быстро, что в 64-битных, что 32-битных системах, но это к делу не относится.

Итак, первая строка результата просто кричит: "Пользуйтесь 32-битными приложениями в 64-битных системах и будет ВАМ ЩАСТЬЕ!"
Где я не прав?
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: 32vs64

Сообщение Sergei I. Gorelkin » 26.12.2013 14:01:47

Имеется в виду "пользуйтесь 32-битными типами на 64-битных системах"?
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 32vs64

Сообщение hovadur » 26.12.2013 19:10:31

Integer - 32 бит даже для 64-битной системы. Так, что в pascal с этим проблем нет.
hovadur
постоялец
 
Сообщения: 116
Зарегистрирован: 31.01.2013 15:50:41

Re: 32vs64

Сообщение SSerge » 27.12.2013 06:38:30

hovadur писал(а):Integer - 32 бит даже для 64-битной системы. Так, что в pascal с этим проблем нет.

Если брать паскаль как таковой, то integer вообще то 16 бит по стандарту языка. И вообще, причем здесь integer? Речь идет о типах, в которых разрядность задана явным образом - int64 etc.

xdsl
Вообще выводы любопытные, но из вашего сообщения как-то не очень воспринимаются. Ну и довольно странный выбор процессоров - специализированные серверные в основном, если уж озадачиваться, тогда уж тестировать на всех, включая самые первые 64-разрядники, и тогда уж подводить статистику и делать какие-то выводы. А так как-то на уровне догадки пока.
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: 32vs64

Сообщение xdsl » 27.12.2013 07:28:21

Sergei I. Gorelkin писал(а):Имеется в виду "пользуйтесь 32-битными типами на 64-битных системах"?

Нет, именно 32-битными приложениями.
Берете исходник программы на паскале или си, который манипулирует 8-16-32-битными переменными, например (для 32-битных переменных):
Код: Выделить всё
{$mode objfpc}
uses sysutils,dateutils;
const MAX=200000000;
{$IFDEF CPU64} BITS=64; {$ENDIF}
{$IFDEF CPU32} BITS=32; {$ENDIF}
{$IFDEF CPU16} BITS=16; {$ENDIF}
var
     i32,MulDiv32:longint;
     dt:tdatetime;
begin
dt:=now();
i32:=1; MulDiv32:=10;
while i32<MAX do i32:=(((i32+2)*MulDiv32) div MulDiv32)-1;
writeln(millisecondsbetween(now(),dt),' мс: 32-битная арифметика для ',BITS,'-разрядной ОС');
end.


или

Код: Выделить всё
#include <time.h>
#include <stdio.h>
clock_t dt;
long int i32,MulDiv32;
const MAX=200000000;

void main()
{
dt=clock();
i32=1; MulDiv32=10;
while (i32<MAX) i32=(((i32+2)*MulDiv32)/MulDiv32)-1;
printf("%lu\n",(clock()-dt)/(CLOCKS_PER_SEC/1000));
}

компилируете 64-битным компилятором, получаете 64-битный бинарник. Затем компилируете ту-же самую программу 32-битным компилятором, получаете 32-битный бинарник. Оба бинарника запускаете на 64-битной системе и видите, что 32-битная программа работает в 1.5 раза быстрее своего 64-битного аналога.
И да, в сишной компиляции отключить все оптимизации, а то цикл while (i32<MAX) i32=(((i32+2)*MulDiv32)/MulDiv32)-1; может превратиться в одно действие i32=200000000.

SSerge писал(а): Ну и довольно странный выбор процессоров - специализированные серверные в основном, если уж озадачиваться, тогда уж тестировать на всех, включая самые первые 64-разрядники, и тогда уж подводить статистику и делать какие-то выводы.
До каких систем дотянулся. Все 64-битные, все поддерживают работу как 64-битных, так и 32-битных приложений. И как выясняется, 32-битные приложения работают эффективнее.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: 32vs64

Сообщение Sergei I. Gorelkin » 27.12.2013 10:04:41

Ну так 32-битная программа и на 32-битной системе будет работать так же, как и на 64-битной, просто это не проверялось.
И эффективнее, согласно приведенным результатам, все же только с 32-битной арифметикой? Это объяснимо: паскаль производит все вычисления с машинным словом. Нужно сложить два байта - на x64 сложит 8 байт, 7 из которых выбросит. А во всех руководствах по оптимизации для x64 написано: не нужно использовать 64-битные вычисления без явной необходимости, 32-битные выигрывают и по скорости, и по размеру кода.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 32vs64

Сообщение xdsl » 28.12.2013 23:17:09

Sergei I. Gorelkin писал(а):А во всех руководствах по оптимизации для x64 написано: не нужно использовать 64-битные вычисления без явной необходимости, 32-битные выигрывают и по скорости, и по размеру кода.
Как, используя 64-битный компилятор freepascal, заставить его генерировать 32-битные инструкции для 32-битных переменных? Он что для 64-битных, что для 32-битных в обеих формулах ассемблерные команды idivq, imulq, addq и decq генерирует. Разница только в замене movslq для longint на movq для int64. У компилятора Си получше код выходит, но все равно при обработке 32-битных значений никогда не угадаешь, где он 32-битную, а где 64-битную команду сгенерирует.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: 32vs64

Сообщение hinst » 30.12.2013 19:37:00

xdsl, проверил твою программу на своём компьютере, вот какие результаты получил:
Код: Выделить всё
hinst@h-home-pc /cygdrive/d/Dev/wut
$ ./project1.exe
4450 мс: 32-битная арифметика для 64-разрядной ОС
4411 мс: 64-битная арифметика для 64-разрядной ОС

hinst@h-home-pc /cygdrive/d/Dev/wut
$ ./project1.exe
4309 мс: 32-битная арифметика для 32-разрядной ОС
8536 мс: 64-битная арифметика для 32-разрядной ОС

Как видишь, разница очень маленькая получилась, а не в 1.5 раз...

Добавлено спустя 50 секунд:
P.S.: FPC 2.6.2

Добавлено спустя 3 минуты 51 секунду:
P.P.S.: с включённой оптимизацией у меня разница ещё меньше
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: 32vs64

Сообщение xdsl » 01.01.2014 16:24:56

Странные результаты.
1. Что за процессор, OC? Использовалась кросскомпиляция или родной 32-битный компилятор? Запуск неужто под Wine?
2. Хотелось-бы увидеть сгенерированный 32-битным и 64-битным компилятором ассемблерный файл 32vs64.s (fpc -al 32vs64.pp). По нему сразу станет ясно.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: 32vs64

Сообщение hinst » 02.01.2014 18:53:18

xdsl у меня процессор AMD Phenom II X4, О.С. Windows 8.1 64-разрядная без виртуализации, запущена "прямо на компе". Консоль такая потому что я часто использую Cygwin когда надо что-то в консоли сделать

Добавлено спустя 2 минуты 4 секунды:
когда попробовал 64-разрядному компилятору передать настройку -al, какая-то ошибка происходит:
Код: Выделить всё
Assembler ml64.exe not found, switching to external assembling
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: 32vs64

Сообщение Sergei I. Gorelkin » 02.01.2014 19:45:28

hinst писал(а):когда попробовал 64-разрядному компилятору передать настройку -al, какая-то ошибка происходит

Ассемблерный файл при этом все равно создается, просто его пытаются собрать с помощью ml64.exe, которого нет.
Вообще, ассемблер по умолчанию переключили на gnu as уже очень давно...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 32vs64

Сообщение xdsl » 05.01.2014 10:56:35

Должен получиться файл с ассемблерным кодом и расширением .s.
При использовании 32-битного компилятора - с одним кодом, 64-битного - с другим. Я сравнивал содержимое этих файлов, сразу стало понятно, откуда скорость 32-битных приложений берется. 32-битные инструкции в большинстве случаев работают быстрее, чем 64-битные (см. например, сюда: http://www.agner.org/optimize/). Исключения есть, но по совокупности арифметических операций 64-битные системы проседают.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru