Russian Qt Forum
Ноябрь 23, 2024, 10:48 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Флоты и int - старые легенды или как?  (Прочитано 6145 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Февраль 18, 2011, 19:30 »

Добрый вечер

Вопрос конечно "теоретический" но все же интересно разобраться/понять. "С детства" (ну отрочества) вдалбливалось: целочисленная арифметика (намного) быстрее, всегда используйте shl вместо div и.т.п. Но так ли это сейчас (на дворе 2011 год, времена (со)процессоров давно канули в Лету)? Главное что смущает - RISC архитектура. Ведь если RISC - то (в общих чертах) все команды исполняются за 1 такт. Следовательно операции с флотами "столь же быстры" как и с int (ведь и те и те 1 такт). О каком же преимуществе int тогда идет речь?

Лично мои тесты (когда у меня есть такая возможность) показывают что целочисленная арифметика пошустрее но ни о каких "разах" не может быть и речи. А у Вас?

Спасибо
Записан
Fat-Zer
Гость
« Ответ #1 : Февраль 18, 2011, 19:56 »

FPU хоть и включили в ядро, но он всё также лежит отдельным модулем, так что как ни крути... а всё равно медленней... правда моя уверенность тоже пошатнулась, сейчас сам попробую проверить.
Записан
Fat-Zer
Гость
« Ответ #2 : Февраль 18, 2011, 20:29 »

вот что у меня получилось:
Цитировать
int sum time: 0.799162
double sum time: 1.12288
=================================================
int div2 time: 0.00117723
int shift div2 time: 0.00041127
double div2 time: 0.00156852
=================================================
int div3 time: 0.00112485
double div3 time: 0.00300799
=================================================
int div7 time: 0.000802933
double div7 time: 0.0016741
конечно не разы, но 2 раза есть
Код
C
#include <time.h>
#include <unistd.h>
#include <stdio.h>
 
double processCpuTime()
{
struct timespec tp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
return tp.tv_sec + tp.tv_nsec * 1.0e-9;
}
 
int main()
{
int i;
int ii;
const int maxii=0xfffffff;
double id;
const int maxid=maxii;
double time=processCpuTime();
 
for(ii=0;ii<maxii;ii++);
printf("int sum time: %g\n",processCpuTime()-time);
 
time = processCpuTime();
for(id=0;id<maxid;id++);
printf("double sum time: %g\n",processCpuTime()-time);
 
printf("=================================================\n",processCpuTime()-time);
 
time = processCpuTime();
for(i=0;i<10000;i++)
for(ii=maxii;ii>1;ii/=2);
printf("int div2 time: %g\n",processCpuTime()-time);
 
time = processCpuTime();
for(i=0;i<10000;i++)
for(ii=maxii;ii>1;ii>>=2);
printf("int shift div2 time: %g\n",processCpuTime()-time);
 
time = processCpuTime();
for(i=0;i<10000;i++)
for(id=maxid;id>1;id/=2);
printf("double div2 time: %g\n",processCpuTime()-time);
 
printf("=================================================\n",processCpuTime()-time);
 
time = processCpuTime();
for(i=0;i<10000;i++)
for(ii=maxii;ii>1;ii/=3);
printf("int div3 time: %g\n",processCpuTime()-time);
 
time = processCpuTime();
for(i=0;i<10000;i++)
for(id=maxid;id>1;id/=3);
printf("double div3 time: %g\n",processCpuTime()-time);
 
printf("=================================================\n",processCpuTime()-time);
 
time = processCpuTime();
for(i=0;i<10000;i++)
for(ii=maxii;ii>1;ii/=7);
printf("int div7 time: %g\n",processCpuTime()-time);
 
time = processCpuTime();
for(i=0;i<10000;i++)
for(id=maxid;id>1;id/=7);
printf("double div7 time: %g\n",processCpuTime()-time);
 
 
}
 
« Последнее редактирование: Февраль 18, 2011, 20:32 от Fat-Zer » Записан
Akon
Гость
« Ответ #3 : Февраль 18, 2011, 20:55 »

Когда то для процессора Pentium III Tualatin делал на асме высокооптимизированные алгоритмы ЦОС с использованием MMX и XMM (челочисленные и с плавающей точкой SIMD расширения соответственно). С XMM было чуть-чуть медленнее, в общем, сопоставимый результат.
Записан
Fat-Zer
Гость
« Ответ #4 : Февраль 18, 2011, 21:23 »

Когда то для процессора Pentium III Tualatin делал на асме высокооптимизированные алгоритмы ЦОС с использованием MMX и XMM (челочисленные и с плавающей точкой SIMD расширения соответственно). С XMM было чуть-чуть медленнее, в общем, сопоставимый результат.
xmm так вроде регистры sse называются. Но всё это уже совсем другие яица... я так понял сабж именно про FPU  и на сколько он реально отстаёт от обычной целочисленной арифметики. Да и понятно, почему не большая разница в скорости, всё же sse появился сильно позже mmx.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Февраль 18, 2011, 22:18 »

Исходя из этого:
Цитировать
Число с плавающей запятой состоит из:
  • Мантиссы (выражающей значение числа без учёта порядка)
  • Знака мантиссы (указывающего на отрицательность или положительность числа)
  • Порядка (выражающего степень основания числа, на которое умножается мантисса)
  • Знака порядка
если FPU является блоком в CPU, то целочисленная арифметика по определению будет быстрее.
Записан

Qt 5.11/4.8.7 (X11/Win)
brankovic
Гость
« Ответ #6 : Февраль 18, 2011, 23:46 »

Исходя из этого:
Цитировать
Число с плавающей запятой состоит из:
  • Мантиссы (выражающей значение числа без учёта порядка)
  • Знака мантиссы (указывающего на отрицательность или положительность числа)
  • Порядка (выражающего степень основания числа, на которое умножается мантисса)
  • Знака порядка
если FPU является блоком в CPU, то целочисленная арифметика по определению будет быстрее.

сейчас самые задержки в процессоре на сбоях конвейера, потому что с памятью (и даже кэшем) работа намного медленнее, чем с регистрами. Один останов и перезаполнение конвейера могут стоить дороже нескольких арифметик. Даже если согласиться, что инты и правда 'по определению быстрее', то остаётся вопрос на сколько. Если на 0.01% то это всё равно что не быстрее. Если же на 50% то другое дело.
Записан
Fat-Zer
Гость
« Ответ #7 : Февраль 19, 2011, 08:27 »

Даже если согласиться, что инты и правда 'по определению быстрее', то остаётся вопрос на сколько. Если на 0.01% то это всё равно что не быстрее. Если же на 50% то другое дело.
см. мой пост(#3) получается, что в 2 раза... хотя я рассчитывал на 3-7 раз...
Записан
brankovic
Гость
« Ответ #8 : Февраль 19, 2011, 09:59 »

Даже если согласиться, что инты и правда 'по определению быстрее', то остаётся вопрос на сколько. Если на 0.01% то это всё равно что не быстрее. Если же на 50% то другое дело.
см. мой пост(#3) получается, что в 2 раза... хотя я рассчитывал на 3-7 раз...

мне показалось тест не очень чистый но сейчас смотрю -- нормальный тест. Надо ещё с SSE2 сравнить. SSE2 должен инты побить Улыбающийся
Записан
Fat-Zer
Гость
« Ответ #9 : Февраль 19, 2011, 10:41 »

мне показалось тест не очень чистый но сейчас смотрю -- нормальный тест. Надо ещё с SSE2 сравнить. SSE2 должен инты побить Улыбающийся
а gcc оказывается хитрый жук... посмотрел асм код, а он всю FPU арифметику как SSE расписал...
перекомпилировал:

$ gcc -O0 -mfpmath=387 -lrt 2.c
$ ./a.out
int sum time: 0.792594
double sum time: 1.12118
=================================================
int div2 time: 0.00117913
int shift div2 time: 0.00040503
double div2 time: 0.00157286
=================================================
int div3 time: 0.00114019
double div3 time: 0.00339716
=================================================
int div7 time: 0.000804634
double div7 time: 0.00189564

в итоге результаты немного хуже, но почти незначительно.
ЗЫ: SSE2 это вы про целочисленную арифметику имеете в виду? тогда тест должен быть более мудрёный... например 2-4 числа одновременно увеличивать(делить) в цикле, а на тыком простом скорей всего ничего не получится, хотя надо пробовать Улыбающийся
ЗЗЫ: на всякий случай система x64
ЗЗЗЫ: надо бы это всё на асме переписать...
« Последнее редактирование: Февраль 19, 2011, 11:18 от Fat-Zer » Записан
brankovic
Гость
« Ответ #10 : Февраль 19, 2011, 12:10 »


$ gcc -O0 -mfpmath=387 -lrt 2.c


а почему не -O3?

например 2-4 числа одновременно увеличивать(делить) в цикле, а на тыком простом скорей всего ничего не получится, хотя надо пробовать Улыбающийся

хочется циклы немного развернуть вообще, чтобы больше обращений к памяти было, а то на холостом ходу крутится в регистрах. Ещё хотел с CUDA посравнивать, но сейчас времени нет, если руки дойдут опубликую.
« Последнее редактирование: Февраль 19, 2011, 23:41 от brankovic » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Февраль 19, 2011, 12:49 »

Насчет тестов - часто с картинкой (пикселями) удобнее что-то делать в float и это удобство/общность перевешивает 50-100% выигрыш с int, Я когда-то писал тесты, постараюсь найти и выложить.
Записан
Fat-Zer
Гость
« Ответ #12 : Февраль 20, 2011, 11:46 »

чего-то мой пост не добавился...
а почему не -O3?
Потому что -O3 занимается лишней самодейтельностью, например делает все циклы целочисленными или просто убивает их, ибо они ничего не делают.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Февраль 20, 2011, 13:07 »

Вот простой но разумный пример в аттаче. Картинку лучше выбирать побольше (ну или увеличить радиус осреднения, сейчас 9). У меня выдает (секунды)

(int) 1.585
(float) 1.721

Т.е. далеко даже до полутора раз
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.1 секунд. Запросов: 22.