Почему в версии 8 используется пометка указателя, а не NaN-бокс?

#pointers #optimization #v8 #javascript-engine #nan-boxing

#указатели #оптимизация #v8 #javascript-движок #nan-бокс

Вопрос:

Сейчас я изучаю внутренности V8. Я узнал, что V8 использует пометку указателя для хранения значений, но задавался вопросом, почему он не использует NaN-бокс.

AFAIK, NaN-бокс лучше, потому что он также может хранить дубли, а не только SMI. Я прочитал это и понимаю (если это правда), почему не использовать NaN-бокс на 32-разрядных платформах. Но на 64-разрядных платформах я не понимаю, почему.

Я подозреваю, что причина как-то связана с SMIS. Возможно, они не могут быть сохранены с использованием NaN-бокса? Я думаю, что они могут. У нас есть 52 лишних бита для них (мы даже можем использовать более 32 бит). Возможно, для этого потребуются дополнительные операции маскирования, которые замедлят вычисление целых чисел? Но нам уже нужно выполнить побитовый сдвиг!

Я не знаю почему. Спасибо всем, кто готов ответить.

Ответ №1:

(Здесь разработчик версии 8.) NaN-бокс и пометка указателя — это варианты дизайна с разными компромиссами, ни один из них не является строго лучшим, чем другой. Решение V8 использовать пометку указателя было принято задолго до того, как я присоединился к проекту, поэтому я могу только предполагать, какие конкретные причины могли быть в то время.

Преимущества пометки указателя заключаются в:

  • значительно меньшее потребление памяти (конечно, на 32-разрядных платформах; с «сжатием указателя» и на 64-разрядных платформах)
  • немного более эффективные (небольшие) целочисленные операции, потому что целочисленные операции большинства процессоров выполняются быстрее, чем их двойные операции. Это может вообще не иметь значения, как только оптимизирующий компилятор войдет в игру.
  • немного более эффективные операции с указателями, потому что вы можете просто добавить скорректированное смещение при доступе к полям объекта (что имеет ту же производительность, что и отсутствие каких-либо трюков с указателем вообще), в отличие от необходимости маскировать нерелевантные части NaN. Это может вообще не иметь значения, как только оптимизирующий компилятор войдет в игру.

Как вы указали, основное преимущество NaN-тегов заключается в том, что он поддерживает полный двойной диапазон, что очень удобно в некоторых ситуациях. Вы можете создать высокопроизводительный движок на основе любого метода.

Комментарии:

1. Спасибо. Что касается второго пункта, я ссылался на него в своем вопросе (слегка неявно), когда я сказал, что у вас 52 бита, я имел в виду, что вы можете хранить в них SMI. Однако битовая маскировка все еще требуется