Порівняння float vs double - stack overflow російською

TL; DR. float. як і очікувалося, швидше double. тому, якщо ви працюєте з великими обсягами даних і вам вистачає точності float. то ви вибираєте float. Якщо точності float недостатньо, то ваш вибір невеликий - double. Якщо у вас взагалі немає ніяких претензій - вибирайте що завгодно, різниці не побачите.

Я, як учасник вищезазначеного спору, вирішив написати відповідь. Для того, щоб зрозуміти, яка буде продуктивність, я вирішив спочатку вивчити трохи теорії, для цього я написав наступний код:

Для якого ми маємо наступний асемблер (gcc):

Це не весь висновок, але тут досить інформації. Для нас цікаві тут дві інструкції: addss. addsd - кожна є SIMD інструкція по роботі з float (перша) і double. Перша думка - треба пошукати мануал, може там написано, що швидше? Такий мануал є. але побіжний огляд показав, що відповіді я там не отримаю - судячи з мануалу ці інструкції повинні виконуватися однаково швидко. Добре. Залишимо цей шлях і спробуємо зібрати попередній код з AVX2 в студії, отримаємо такий asm:

Код практично не змінився, крім того, що операції стали називатися vaddsd і vaddss. Я не став лізти в мануал по цим командам, вважаю що ситуація там схожа з тими, що ми бачили раніше.

Іншим важливим фактором, який може вивести float вперед є його менший вплив на кеш: тому що він в два рази менше, то і навантаження на кеш буде менше. Таким чином, не розпинаючи і не розписуючи більше, отримуємо наступний висновок, який, в цілому, відразу спадає на думку: float швидше ніж double.

Залишилося перевірити це на практиці, для цього використовуємо наступний код:

Зрозуміло, вимірювання досить прості, а аргументація досить поверхнева (я не ставив за мету повноцінне дослідження, в даний момент у мене немає на нього часу), але навіть це показує, що люди стверджують, що потрібно за замовчуванням вибирати double і що double швидше float - не праві.

І ще один тест, де я використав інтрінсікі для підрахунку суми (я може не кращим чином їх використовував, але вже як є - по іншому не вмію):

З таким кодом, на тій же машині, я отримую приріст в 2.3-2.5 рази.

Хороший відповідь, проте виникає питання. Наприклад, чому ми отримуємо приріст лише x1.2-1.3, враховуючи, що за операцію ми можемо обробити 8 float ів і 4 double. За ідеєю різниця повинна бути x2, проте ми її не спостерігаємо. Більш того, мій тест на C # (теж досить простий), показав різницю в продуктивності менш 1%, але теж на користь float. причому порівнювалася продуктивність при простих операціях, тобто не використовувалися функції, які повертають double. Ця різниця наводить мене на думку, що GCC використовує не найоптимальніші інструкції заради забезпечення платформ. - Мстислав Павлов 18 Січня '16 о 11:24

"Чому ми отримуємо приріст лише x1.2-1.3, враховуючи, що за операцію ми можемо обробити 8 floatов і 4 double?" - @ МстіславПавлов, напевно, це вже до мене питання, хоча @ixSci в принципі на нього вже відповів. Подивіться ще раз на АСМ. Тут в основному команди для роботи з пам'яттю. За межами кеша це дійсно повільні команди. По суті, ви зараз порахували не швидкість складання float # 47; double вектор, а швидкість їх завантаження в кеш. Я в своїй відповіді з кодом останній тест якраз робив з помилкою, щоб показати вплив кеша на результат. - mega 18 Січня '16 о 11:48

"Якщо виключити вашу навмисну" помилку ", різниця стане ще менше, я правильно розумію?" - порахуйте самі: передостанній результат - вже без помилки. Мені просто @avp не сказав тоді своїх характеристик для RAM. але показав, що його результати краще, тому я зробив останній "хитрий" тест. @ixSci може зробити такий же тест в своєму останньому прикладі. - mega 18 Січня '16 в 12:49

Спираючись на ту ж архітектуру, можна сказати, що float-операції швидше як мінімум в 2 рази. Для прикладу: в 128-бітному векторному регістрі вміщується 2 double або 4 float. Чому мінімум - тому що на підготовку векторів можуть йти додаткові витрати, які будуть оцінені в тому ж співвідношенні. Від обраної мови тут мало що залежить, скоріше - від компілятора, від його якості оптімізацііонних алгоритмів під задіяння SSE. - mega 18 Січня '16 в 4:47

Схожі статті