Или я не понял посыла статьи, или Вас ждет небольшое разочарование, ведь для синуса/косинуса и ряда других тригонометрических функций есть соответствующие инструкции, и наличие их 128-битных вариантов гарантируется при наличии самого простого SSE.
Что-то я запутался — то кто-то влепил в байт-код ерунду, то его валидирует компилятор. Допускается ли ситуация, что байт-код на входе будет невалидным? Если да, то предлагается предварительно пройтись по всему буферу байт-кода, и для каждого байта проверить, что он является валидной инструкцией. Профит тут очевиден — когда в программе есть циклы (всегда), мы вместо N проверок на валидность тела цикла проверим его только один раз.
Тогда, использовав в switch'е пометку про недостижимость ветки default, информируем компилятор о том, что все инструкции валидны. Тогда если сравнивать с изначальным вариантом, то мы избавляемся от лишнего прыжка, если с оптимизированным — от лишнего логического «и».
Про корректность — имеется в виду упражнение второе. В конце концов, все равно делается побитовое «и». Мне кажется, лучше было бы вообще не проверять корректность инструкции на данном этапе:
uint8_t instruction = NEXT_OP();
/* Let the compiler know that opcodes are always between 0 and 31 */
switch (instruction) {
/* All the instructions here */
default: {
__builtin_unreachable();
}
}
В этом случае лишних действий вообще нет. А если есть риск, что код может оказаться некорректным, просто предварительно пройтись по буферу и сделать чисто проверки на корректность.
Про SIMD — имелось в виду введение непосредственно инструкций, аналогичных Intel SSE, например взять из стека два вектора значений, просуммировать, и результат засунуть в стек. Но вообще это шутка была.
Зачем вообще проверять инструкции на корректность в рантайме? Как минимум можно это сделать отдельно от выполнения — тогда в случае циклов не будем дублировать эти проверки над одними и теми же данными.
Еще возможно стоит попробовать организовать хранение нескольких верхних значений стека в регистрах, а не в памяти — скорость доступа к ним наиболее важна.
P. S. Примечательно, что суперинструкции дали такой прирост. Ждем поддержку SIMD))
Ну VS уже больше 15 лет существует, никто никем не вертит. А даже если начнет — да, придется один раз конвертировать solution VS в solution чего-то другого, но Вы это сделаете один раз, причем, скорее всего, не вручную, а автоматически. С другой стороны, Вам не придется все тестить в десятке IDE и мучиться с CMake.
1) В VS 17 вроде есть Linux Toolkit. Ну и вообще вряд ли Вы потратите больше времени с IDE, чем с обычным редактором.
2) VS умеет в C++, C#, Python, JavaScript, это то что я с ходу назову. Вроде норм мультиязычность.
3) Что в этом плохого?
4) Ну такими темпами и язык программирования то наверняка не всем по душе) И операционка/политика компании/положение звезд на небе. Отчасти поэтому смотрят и в сторону популярности IDE среди программистов, и VS Code там не на первом месте.
Вообще, если у Вас кроссплатформенный проект с тонной условностей вроде своей build-системы и каких-то редких диалектов языков, то VS и впрямь может быть не лучшим выбором. Но согласитесь, что автор проблемы может испытать только в четвертом пункте)
Ну, если и сборка кастомная, и плагинов по-находили, то VS Code может быть и неплохой инструмент. Но все это у Вас есть только потому, что кто-то когда-то потратил уйму времени на то, что бы все это сделать. И в этом отличие Вашего понимания IDE от моего. ИМХО IDE — это Integrated Development Environment, то есть после ее запуска я должен иметь возможность редактировать/компилировать/запускать/дебажить/в случае VS еще и мало-мальски профилировать CPU и дебажить графику. Максимум что нужно сделать — пару настроек на вкус и цвет.
Насколько я знаю, обычно используют VS. Community edition безусловно-бесплатная, имеет очень развитый функционал, не лагает, ну а для профилирования и компьютерной графики там вообще все шикарно (по сравнению с другими IDE). Но, насколько я понимаю, все это перекрывается одним большим минусом — ее сделали не в JetBrains?
Очень любопытная картина: после сообщения о том, что Вы пришли в область, в которой ничего не смыслите, Вы сразу же классифицировали всех несогласных с Вашими решениями на три не очень приятные категории. Вы не рассматриваете четвертую категорию — тех, кто уже крутится в данной области, и лучше знает, что больше подойдет для задачи?
Если бы Вы выбрали IDE, которая используется как раз для разработки десктопа под Windows, в этой статье вместо двадцатиминутной возни с CMake в VS Code Вы бы уже писали игрушки.
Вы можете узнать эти ограничения через cudaGetDeviceProperties. Но они совершенно неадекватные, просто для галочки. На 940MX они составляют 2147483647 x 65536 x 65536, видимо, только для того, что бы какие-то счетчики не переполнились. Так что можно запускать на сколько угодно блоков, просто одновременно будут исполняться только 1280 (на Geforce 1060).
Кстати, о самом то важном и не сказал, измерять время в CUDA-реализации с помощью clock() — не очень правильно, в CUDA для этого есть cudaEvent_t.
Спасибо за статью, хорошую задачу подобрали.
1) ИМХО Вы очень зря используете 16 процессоров на 16 потоков. Во-первых, у процессора 32 потока, так что половина из них просто стоят, во-вторых, если у Вас десктопная видеокарта, то процессоров там явно больше тысячи. Странно сравнивать CPU и GPU, задействуя при этом все потоки процессора, и игнорируя большую часть ресурсов видеокарты.
2) Думаю, если Вы откажетесь в CPU реализации от использования std::set, она взлетит как гордый орел.
3) Еще на счет CPU, не думали задействовать векторные инструкции? Все таки без них потенциал не полностью раскрыт.
И укажите, пожалуйста, железо, на котором проводились тесты.
Очевидно что, пример — это просто пример, там ведь Sleep на одну секунду. Но на счет синхронизации — не всегда стоит использовать системные event'ы, так как они обычно довольно дорогие. Если нужно уйти в сон на ~ микросекунду — лучше делать spin-lock.
Да, подзабыл про них. Но насколько я знаю, барьеры — это сильно легче чем мьютексы (в плане производительности).
нужно отмечать как unsafe.
Ну так то да, но обсуждение началось с утверждения будто необходимость ставить volatile и пользоваться атомарными операциями в плюсах — это повод переходить на Rust. А я привел пример задачи, с которой мирок Rust'а не справляется, и нужен мирок C++.
Только что проверил тут, вроде все как надо.
Тогда, использовав в switch'е пометку про недостижимость ветки default, информируем компилятор о том, что все инструкции валидны. Тогда если сравнивать с изначальным вариантом, то мы избавляемся от лишнего прыжка, если с оптимизированным — от лишнего логического «и».
В этом случае лишних действий вообще нет. А если есть риск, что код может оказаться некорректным, просто предварительно пройтись по буферу и сделать чисто проверки на корректность.
Про SIMD — имелось в виду введение непосредственно инструкций, аналогичных Intel SSE, например взять из стека два вектора значений, просуммировать, и результат засунуть в стек. Но вообще это шутка была.
Еще возможно стоит попробовать организовать хранение нескольких верхних значений стека в регистрах, а не в памяти — скорость доступа к ним наиболее важна.
P. S. Примечательно, что суперинструкции дали такой прирост. Ждем поддержку SIMD))
Может все таки «обеспечения»?
2) VS умеет в C++, C#, Python, JavaScript, это то что я с ходу назову. Вроде норм мультиязычность.
3) Что в этом плохого?
4) Ну такими темпами и язык программирования то наверняка не всем по душе) И операционка/политика компании/положение звезд на небе. Отчасти поэтому смотрят и в сторону популярности IDE среди программистов, и VS Code там не на первом месте.
Вообще, если у Вас кроссплатформенный проект с тонной условностей вроде своей build-системы и каких-то редких диалектов языков, то VS и впрямь может быть не лучшим выбором. Но согласитесь, что автор проблемы может испытать только в четвертом пункте)
Что имеется в виду?
И VS Code — это не та IDE, которую используют для десктопа под Windows.
Если бы Вы выбрали IDE, которая используется как раз для разработки десктопа под Windows, в этой статье вместо двадцатиминутной возни с CMake в VS Code Вы бы уже писали игрушки.
Кстати, о самом то важном и не сказал, измерять время в CUDA-реализации с помощью clock() — не очень правильно, в CUDA для этого есть cudaEvent_t.
1) ИМХО Вы очень зря используете 16 процессоров на 16 потоков. Во-первых, у процессора 32 потока, так что половина из них просто стоят, во-вторых, если у Вас десктопная видеокарта, то процессоров там явно больше тысячи. Странно сравнивать CPU и GPU, задействуя при этом все потоки процессора, и игнорируя большую часть ресурсов видеокарты.
2) Думаю, если Вы откажетесь в CPU реализации от использования std::set, она взлетит как гордый орел.
3) Еще на счет CPU, не думали задействовать векторные инструкции? Все таки без них потенциал не полностью раскрыт.
И укажите, пожалуйста, железо, на котором проводились тесты.
Ну так то да, но обсуждение началось с утверждения будто необходимость ставить volatile и пользоваться атомарными операциями в плюсах — это повод переходить на Rust. А я привел пример задачи, с которой мирок Rust'а не справляется, и нужен мирок C++.