Мы видели ранее, что LightGBM был чрезвычайно быстрым, намного быстрее, чем xgboost с настройками по умолчанию в R. Недавно, чтобы исправить ошибку прогнозирования в LightGBM, было сделано переключение с float на double (для функций, связанных с прогнозированием), чтобы исправить этот вопрос. Теперь, когда изменение официальное, давайте попробуем несколько тестов, чтобы проверить возможные различия в производительности.

Общий обзор

Не будем молчать, а сразу перейдем к результатам бенчмарка. Что касается использования ОЗУ, то во время обучения мы увеличили примерно с 1425 МБ (с плавающей запятой) до 1434 МБ (двойное), что не имеет большого значения для более чем 1 миллиона наблюдений.

Разница не кажется незначительной, но на самом деле она незначительна для большинства из них. Мы наблюдаем разницу до 3,3 секунды для одного потока продолжительностью более 200 секунд, что составляет около 1,7% потери производительности при переключении с float на double.

Помните, что двойное представление длины в памяти вдвое больше, чем число с плавающей запятой. По мере увеличения количества потоков тенденция потерь при переключении с float на double становится либо обратной, либо нулевой.

Относительная производительность

Угадайте, что лучше? Можешь попробовать.

Чем больше количество потоков, тем меньше вероятность влияния на производительность. Это что-то положительное, если вы запускаете много потоков, чтобы перегрузить ЦП. Если вы не можете использовать многопоточность, вы можете получить более медленную программу при переключении с float на double. В остальном разница незначительна, если не все дело в случайном шуме.

Главный вопрос: можем ли мы это объяснить?

Кеширование удовольствия

Вы знаете, что такое кеширование? Это то, о чем мы быстро поговорим здесь. А также, почему кэширование важно и важно.

Почему, черт возьми, двойное представление памяти лучше, чем одно представление памяти?: Это все о кэшировании (ЦП).

Если вы хорошо кешируете, то вы будете получать информацию очень быстро. Например, в условных циклах кэш может быть решающим фактором производительности, до 3 раз, а иногда и больше! (только для использования кеша?!)

В случае с LightGBM речь идет о многопоточности и кэшировании. Если вы заполняете кеш «плохими» данными, то вы плохо наполняете кеш и теряете время.

Карикатурное объяснение

Возьмите этот сценарий:

  • Вы собираетесь приготовить наггетсы на ужин (то, что вы ищете)
  • Первый (L1) «тайник» у вас есть приготовленная тарелка с печеньем рядом с вами
  • Второй (L2) «кеш» у вас есть приготовленная пицца в следующем куске
  • Третий (L3) «тайник» — это приготовленная миска на одну ступеньку выше.
  • Четвертый (ОЗУ) «кэш» у вас есть, чтобы готовить наггетсы на кухне

Вопросы:

  • Вы рассчитываете приготовить наггетсы на кухне быстрее, чем подняться наверх, чтобы проверить миску? Нет, очевидно. Вы потеряете время.
  • Ожидаете ли вы сделать последнее быстрее, чем переходить к следующему фрагменту? Нет конечно. Вы потеряете время.
  • Ожидаете ли вы сделать последнее быстрее, чем проверять тарелку с печеньем рядом с вами? Нет, это 100% уверен, что вы не сможете сделать это быстрее. Вы потеряете время.
  • Сколько времени вы бы потеряли, готовя наггетсы, по сравнению с тем, чтобы взять наггетсы в тарелке для печенья (если бы она там была)? Много!

Это примерно то, что представляет собой штраф за промах кэша (очень карикатурно). Промахов кеша бывает так много, что вы даже сами их не видите.

Хорошее кэширование

Представьте, что теперь у вас нет промахов кеша, идеальный сценарий. Если ваши тайники ограничены, вы не сможете поместить все эти самородки в тарелку для печенья. Вы бы положили их на свою пиццу после этого, затем на миску на одну ступеньку выше, пока вам не пришлось бы готовить наггетсы самостоятельно.

Если вы уменьшите кеш в два раза по предыдущему сценарию, вы с большей вероятностью пойдете к своей пицце, подниметесь наверх и, в конце концов, приготовите ее сами. Когда вы переключаетесь с float на double, вы удваиваете требуемое использование памяти. Поэтому, если вы не можете уместить столько же самородков, сколько раньше, вы будете медленнее работать с удвоениями против чисел с плавающей запятой!

Плохое кэширование

Представьте, что сейчас вы кладете в свои тайники много хлама, вроде пиццы и печенья. Если вы подходите к своей тарелке с печеньем и видите печенье, вы недовольны и идете в пиццу. Но ты видишь пиццу, так что иди наверх. Вы не находите свой самородок, поэтому идете на кухню и делаете его сами, и вы потеряли много времени!

Когда вы уменьшите тайники вдвое, вы, скорее всего, пойдете на кухню быстрее, чем изначально. Угадайте, что?: кеширование настолько плохое, что вы предпочитаете чаще ходить на кухню, чем изначально. Если у вас меньше объектов в кеше для проверки, то вы, вероятно, работаете быстрее: именно это и происходит, когда вы используете многопоточность. Если вы заполните кеш мусором, вы получите мусор. Но с меньшим количеством хлама вы становитесь быстрее, чем слишком много хлама.

Следующие тесты?

Я все еще жду, когда метод быстрой гистограммы xgboost заработает в R и будет объединен с основной веткой. Затем я скомпилировал xgboost и начал проводить тесты для сравнения xgboost и LightGBM в сравнении «Apple to Apple»!