#Принципы Scope
В основу Scope заложены принципы:
0. Realtime
Симуляции должны работать в режиме реального времени, для инсайта принципиально необходим FPS выше 30-40 кадров в секунду, оптимально равно или выше частоты обновления монитора.
В идеале чем выше частота симуляции, тем субьективно приятнее и “живее” она воспринимается.
По сравнению с вычислениями, визуализация обычно стоит 5-10% от общей производительности системы, часто и того меньше, поэтому на частоты визуализации в диапазоне 60-120 Hz, являются оптимальными для большинства мониторов.
1. 100% производительность
Симуляции, создаваемые на Scope, должны обеспечивать производительность, не уступающую той, которую, по крайней мере лично я, в состоянии достичь, написав всё “на голом С++ и CUDA”.
100% производительность является решающим фактором, обеспечивающим качественный инсайт созерцательных сеансов медитативного восприятия. Если производительность не на высоте, инсайта не будет, не будет мотивации, не будет точного понимания, или, я бы даже сказал, ощущения, что нужно делать дальше.
под производительностью понимается максимальный FPS визуализации + максимальная частота обновления физических моделей + максимальное число элементов, обрабатываемых физическими моделями
2. весь рантайм на GPU
это условие является синергетическим продолжением пункта 1.
при современном “классическом GPGPU программировании”, видеокарта чаще всего производит перерасчёты свойств уже существующих в памяти систем объектов, скопированных на неё из памяти CPU либо в виде упорядоченных структурных объектов:
struct Point {
float3 pos;
float3 vel;
float3 rgb;
};
// аллоцировать память под 100000 точек
points Point[ 100000 ];
в таком случае, kernel’ы GPU по сути представляют собой “параллельные циклы” по этим структурам
for (int i = 0; i < 1000000; i++){
// перемещаем все точки
points[i].pos += points[i].vel;
};
часто такие множества имеют статичное количество экземпляров, совпадающее с количеством физически выделенной памяти, которая аллоцируется под нужное количество объктов заранее.
- типичным примером таких структур данных являются нейросети со статичной структурой (количеством нейронов, синапсов и их общей конфигурацией). Например, TensorFlow, насколько я понимаю, выделяет под понятие Tensor именно такую статично аллоцируемую структуру данных. С этой точки зрения, на TensorFlow должно быть принципиально сложно реализовать любые виды нейросетей, которые должны динамически образовывать и уничтожать нейроны и/или синапсы.
если же возникает необходимость добавлять или удалять экземпляры множеств, то данные копируются в память CPU и там осуществляется вся необходимая рутина по менеджменту памяти
такая особенность ключевым образом ограничивает ВСЁ существующее на сегодня GPU программирование:
симуляции, в которых большие подмножества объектов должны динамически создаваться и уничтожаться - начинают лагать в момент существенного перестроения систем взаимосвязанных множеств, например:
- системы нейронов и синапсов в нейросетях
- точки массы (ноды) и рёбра жёсткости(линки) в физических симуляциях
из раннего опыта, на примере физического движка и ранней модели sst.exe, написанной как раз в классической манере CUDA GPU программирования:
когда материя, составленная из нод и линков, рвалась, нужно было на каждом кадре симуляции в больших количествах уничтожать линки между нодами, что вызывало лаги, если происходило одновременное повреждение большого количества ткани (пресловутые “лаги при мощных взрывах”, присущие многим современным играм, имеют под собой ту же природу)
примером необходимости в больших количествах динамически создавать объекты, является, например, модель рекурентной нейросети, в которой на каждом шаге динамически образуются и разрушаются связи, вместо создания матрицы связей “каждый с каждым”, что принципиально невозможно для достаточно больших графов (т.е. полносвязные нейросети Хопфильда - это небольшие сильносвязанные графы, в то время как речь идёт о больших слабосвязанных графах, вроде онтологических схем)
с точки зрения производительности, здесь есть два “поражающих фактора”:
- процессор модифицирует модели данных в памяти последовательно, поэтому попытки одномоментно создать/удалить количества объектов, соотносимые с общим количеством обрабатываемых в реальном времени GPU объектов приведут к лагам:
GPU обрабатывает миллионы объектов сотни раз в секунду, в то время как CPU в состоянии обрабатывать как максимум сотни-тысячи удалений/добавлений объектов в секунду
- для обработки данных процессором, их ещё нужно скопировать с видеокарты на хост, причём, в силу упорядоченности, копируются всегда все объекты данного класса, что существенно снижает производительность симуляции при количествах объектов выше сотни тысяч, в то время как если полностью избежать необходимости копирования данных между CPU и GPU, возможно создание симуляций, содержащих миллионы объектов, работающих с частотой в сотни тактов в секунду
Итак. Принцип “весь рантайм на GPU” делает возможным:
- создание и удаление любого количества объектов в реальном времени
- работу с миллионами объектов, вместо сотен тысяч
3. Возможность описывать сложные модели.