LINUX.ORG.RU

Скорости разработки и исполнения, не достижимые на С

 ,


2

6

В одном из соседних топиков дали ссылку на хабровскую статью http://habrahabr.ru/post/182428/ c таким вот незатейливым названием.

Статья развесистая, заумная, там и дизассемблированный код, и какие-то адовые формулы, видно что автор подошел к делу основательно, язык С окончательно разгромлен, вот цитата из заключения:

Я показал, как с помощью C++–шаблонов реализовать вычисления и кросс-аппаратную оптимизацию во время компиляции для получения ускорения в 3.5-5.3 раза для реальной задачи. Нет таких оптимизаций в C, которые бы нельзя было применить в C++, т.к. имеется почти полная обратная совместимость. А вот в C – единственная альтернатива C++–шаблонам для подобных оптимизаций – это писать десятки, сотни и тысячи функций – вот уж где действительно copy-paste.

По большому счету, можно было бы пожать плечами и пройти дальше, я помню статьи приблизительно такого же накала вроде «как я вызываю виртуальные функции в 5 раз быстрее чем обычные», «наследование, инкапсуляция, полиморфизм - нереально быстрая разработка и последние гвозди в крышку гроба С» и т.п.

Но автор пишет «Вычисление факториала нам понадобит_ь_ся», с мягким знаком, я сам не заметил как глаза налились кровью, как скачал его код и стал разбираться.

Для тех кому лень читать статью суть такова:

Есть массив структур, автор хочет без индексов, последовательным перебором, быстро выбирать из него записи по каким-то критериям (фильтрам). Организация данных немного странная, ему в каментах сказали что можно бы «Сменить AoS на SoA» (Array of Structures на Structure of Arrays), но это осталось без ответа. Ну, хорошо, допустим что данные есть только в таком виде.

Да, все считается в один поток, на CPU.

Фильтры задаются в виде каких-то границ, в которых должно быть значение, и флага, нужно ли применять фильтр к этому полю.

Неоптимизированный вариант выглядит так: for по всем элементам, внутри цикла смотрим для каждой записи, нужно ли фильтровать по этому полю, и если да, то уже дальше проверяем попадает ли значение в диапазон.

Оптимизированный вариант: берем фильтр, анализируем его, и на основании анализа флагов запускаем циклы по всем записям. Для каждого набора флагов цикл свой. Внутри цикла уже не пересматриваем каждый раз флаги фильтра а просто смотрим, попадает ли нужное значение в диапазон.

Дальше автор приступает к селективности. В этом месте начинается магия с факториалами, формулами, в такие моменты хочется пропустить этот кусок текста и написать «В кои-то веки толковая статья про C++ в которой на живом примере показан нетривиальный способ использования шаблонов. Автор молодец.»

Насколько я понял (поправьте, если неправильно) посыл такой: если считать что данные распределены равномерно, проверку надо начинать с полей, у которых больше бит, так будет быстрее.

Ну и приводит решение с оптимизацией шаблонами. Там не очень большой файл, но когда я попробовал собрать (gcc 4.7.2) - изумился. Он собирается _несколько минут_ (да!). Интересно, как народ с этим работает? Используют pch? В общем, пришлось вынести код search в отдельную единицу трансляции.

Еще странный момент - он измеряет время вызовов функций clock()-ом. У меня он давал какие-то совсем дискретные значения, заменил на gettimeofday().

Мое решение - генератор кода на С (автор в каментах напирает на то что у него решение исключительно на С++, хорошо, пусть будет только С) здесь

Генератор очень простой - он проходит все возможные комбинации флагов фильтров (2**5) и для каждой комбинации делает свой for. То есть фактически то же самое что и в статье, но прямо в лоб

Итог, повторюсь, такой: решение «на С» почти такое же по скорости как и «на С++» (на единицы процентов быстрее). Скорость разработки - ну-у, даже у меня, не очень быстрого разумом, на это ушло всего часа 4

P.S. procoder99, можешь не возбуждаться, это на самом деле тонкий троллинг сишников (единицы процентов за 4 часа, ха-ха), я знаю как на С++ сделать быстрее

Deleted

Последнее исправление: cetjs2 (всего исправлений: 1)

procoder99, можешь не возбуждаться

ахаха, так и будет.

Я так и не понял, ты написал на си решение чуть-чуть быстрее, чем автор - на с++, но ты можешь на с++ быстрее, чем твое на си?

cdshines ★★★★★
()
Последнее исправление: cdshines (всего исправлений: 1)

Но автор пишет «Вычисление факториала нам понадобит_ь_ся», с мягким знаком, я сам не заметил как глаза налились кровью, как скачал его код и стал разбираться.

Это вин!

yoghurt ★★★★★
()

Итог, повторюсь, такой: решение «на С» почти такое же по скорости как и «на С++» (на единицы процентов быстрее)

Ииии... какой вывод? Что кастомный генератор кода генерирует такой же быстрый код, как шаблоны?

tailgunner ★★★★★
()

Читал статью ещё вчера (или позавчера).

за 4 часа, ха-ха

И не влом было столько времени тратить на очевидные вещи?

«Вони шукають те чого нема, щоб доказать що його не існує.»

nanoolinux ★★★★
()

Кое-кто повёлся на троллинг.

Ну и приводит решение с оптимизацией шаблонами. Там не очень большой файл, но когда я попробовал собрать (gcc 4.7.2) - изумился. Он собирается _несколько минут_ (да!). Интересно, как народ с этим работает?

Не используем шаблоны.

quiet_readonly ★★★★
()

Он собирается _несколько минут_ (да!)

пфф... хуйня. Тут парсер с генератором на boost spirit и karma при компиляции сжирает 5G памяти, из-за чего собрать файл на 32-битных платформах становится невозможно. Это один .cpp файл, да.

anonymous
()

я сам программирую на с++, но прочитав это

я покажу как ускорить такой поиск в 3.5-5.3 раза с использованием C++ независимо от аппаратной платформы

дальше читать не стал...какой только ерунды не пишут на хабре...

mbivanyuk ★★★★★
()

Ну сравни свою какашку с нормальным кодом на шаблонах.

anonymous
()
Ответ на: комментарий от geekless

Соснули не кресты, а шаблоны. Засунуть всё в целочисленную переменную и сдвигами&масками извлекать поля можно и на спп.

nanoolinux ★★★★
()
Ответ на: комментарий от geekless

Ага, точно. http://habrahabr.ru/post/182588/

Они с другой стороны зашли, битовой арифметикой. И изменили данные. Ускорили в несколько раз на 64 битах, хотя он и пишет «Разумеется, мне повезло с 62 битами»

Если уж изменять данные, то можно было бы как-то радикальнее, сделать SoA, как они же и пишут, или вообще проиндексировать. А если битово арифметировать, то тогда уже и SIMD.

Впрочем, автор это все (+ GPU и многопоточность) обещает в продолжении, интересно будет посмотреть

Deleted
()

если считать что данные распределены равномерно, проверку надо >начинать с полей, у которых больше бит, так будет быстрее.

Я бы сделал наоборот, ну, может, я что-то не понимаю, конечно.

den73 ★★★★★
()

Лол, тред исполнен лютого БУГУРТА плюсофобов.

Признайтесь себе в том, что ваш процедурный поезд ушел, а будущее за ООП и generic программированием.

anonymous
()

Не, не. Прокодер не прощает и не забывает. Ты слишком слабо подошел к процессу, и ты не учёл самое главное - это его тотальный слив на оптимизации под все архитектуры.

Царь никогда не соревнуется с щитом. Усложнение стиль анскилледа - ты не должен по нему идти - любая задача решается просто.

Царь даёт тебе путь:

#include <stdio.h>
#include <stdint.h>

typedef enum {
  shit_age = 1, shit_code = 2
} shit_t;


inline void shit_search(shit_t mask) {
  if(mask & shit_age)
    fprintf(stderr, "shit_age\n");
  
  if(mask & shit_code)
    fprintf(stderr, "shit_code\n");
}

int main(void) {
  shit_search(shit_age | shit_code);
  
  
  shit_search(shit_code);
  
  
  shit_search(shit_age);  
  return 0;
}

procoder99
()
Ответ на: комментарий от procoder99

Оно настолько возбудилось, что даже сгенерило код!

false ★★★★★
()

Если ничего не путаю там кто-то еще на джаве этот пример сделал, и у него на это времени тратиться меньше чем в С/С++, хотя как такое может быть я не понимаю

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от procoder99

Где код, жалкий выблядок? Нет кода - нет права пиздеть.

anonymous
()
Ответ на: комментарий от anonymous

ООП и generic в сях есть, только корявые.

Reset ★★★★★
()
Ответ на: комментарий от anonymous

Там была сложная система - но я её выпилил, а так да - приучайтесь юзать stdint.

procoder99
()
Ответ на: комментарий от Boy_from_Jungle

Да ничего там не тратится - эти примеры полный щит, начиная от clock() - заканчивая вообще всем.

Они бенчат одним вызовом функции с константыми параметрами - это щит. На реальном бенче их Си С++ и прочее версии будут выдавать примерно одно время.

procoder99
()

Обмазывание шаблонами не нужно. Это уже похоже на программирование ради программирования, а не ради решения задач

johnson102
()
Ответ на: комментарий от johnson102

Почему не ради решения? Я сам видел проект, где действительно можно было гибко настраивать систему, передавая другой аргумент шаблону(вот прям как учил Александреску). Все было красиво и к месту. Другое дело, что таких проектов крайне мало, а программистов, способных работать в такой команде - еще меньше. Потому я тоже за сишечку. Но из-за людей.

forCe
()
Ответ на: комментарий от kamre

Вообще да, есть такое дело. Хотя этот эффект скажется только при достаточно малом размере поля, по сравнению с числом записей. Зато короткие поля быстрее сравнивать. Так что неоднозначно.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от anonymous

Я тебе, анскильность, показал шаблоны на сишке, которые быстрее компилиются и имеют перфоманс выше, чем у твоих анскиллед С++ шаблонов.

generic в сишке самое лучшее в мире, да и ООП тоже.

anonymous
()

получения ускорения в 3.5-5.3 раза для реальной задачи

Страуструп сам говорил (из книги Masterminds of programming), что разница может достигать лишь 1-3 процентов. Все остальное - проблемы разработчика. Далее можно было не вчитываться в статью и тратить время. Ну, а кто не верит создателю языка - ССЗБ.

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от gh0stwizard

Это сишка вс плюсы? Только из-за того, что сишка часть плюсов, и можно Сикод(примтивный) тупо собрать на плюсах.

Если уж говорить про С++, как новомодную ООП стлбайду с шаблонами и псевдоГЦ, то это тормазящие говно и 1-3% только в мечтах. А именно это понимают под плюсами его адепты.

Да и страуструп тоже анскиллен - он теоретик, который с вменяемой идей продался мейнстриму и несёт фуфел. Верить ему может только термальный адепс С++ секты.

anonymous
()
Ответ на: комментарий от anonymous

Мебель, але! Пора эту свинью по IP банить.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.