Отбор усеченной пирамиды снижает частоту кадров в отладке, но улучшает ее в релизе.

Я делаю игру на основе плитки в SFML и решил реализовать простую отбраковку усеченного прямоугольника, чтобы рисовать только те плитки, которые находятся в области просмотра камеры. Результат удался, так как частота кадров увеличилась втрое! Однако тайник был. При запуске игры в режиме отладки частота кадров вместо этого снижается за счет реализованного отсечения усеченной пирамиды. В отладке она увеличилась с 90 до 30 кадров в секунду, а в релизе — со 100 до примерно 350 кадров в секунду.

Отбор просто проверяет для каждого прямоугольника плитки, пересекается ли он с прямоугольником окна просмотра. Если да, то рисуется. Игра отображает несколько представлений для разделенного экрана, и код выглядит так:

for (unsigned int i = 0; i < views.size(); i++)
    {

....

// Calculate viewport rectangle.
        IntRect viewRect;
        viewRect.width = views[i]->getSize().x;
        viewRect.height = views[i]->getSize().y;
        viewRect.left = views[i]->getCenter().x - views[i]->getSize().x / 2;
        viewRect.top = views[i]->getCenter().y - views[i]->getSize().y / 2;

        // Loop throug level tiles and render them.
        for (unsigned int j = 0; j < tileLayers.size(); j++)
        {
            for (unsigned int k = 0; k < tileLayers[j].size(); k++)
            {
                if (tileLayers[j][k]->collide(viewRect))
                    tileLayers[j][k]->drawSprite(window);
            }
        }

....

bool StaticGameObject::collide(IntRect rectangle)
{
    // Private member variable collisionRect.
    // Width and height is set in constructor.
    collisionRect.left = getPosition().x;
    collisionRect.top = getPosition().y;

    if (collisionRect.intersects(rectangle))
    {
        return true;
    }
    return false;
}

Когда я удаляю вызовы пересечения для прямоугольника, частота кадров возвращается к 90 кадрам в секунду. Я очень смущен тем, почему это происходит.


person LethalJam    schedule 16.02.2016    source источник
comment
Возможно, это связано с оптимизацией компилятора? Скорее всего, ваш код не оптимизирован в режиме отладки, что хорошо, но находится в релизе. Попробуйте временно включить оптимизацию в отладочной сборке, чтобы увидеть, влияет ли это на разницу в частоте кадров.   -  person Conduit    schedule 16.02.2016
comment
Также: добро пожаловать в SO! Если у вас есть какие-либо вопросы о том, как работает наше сообщество, скорее всего, у них есть ответ в справочном центре.   -  person Conduit    schedule 16.02.2016
comment
Спасибо! Я несколько новичок в С++ и Visual Studio. Как изменить оптимизацию компилятора?   -  person LethalJam    schedule 16.02.2016
comment
В VS вы можете получить доступ к этой опции в обозревателе решений. Щелкните правой кнопкой мыши свой проект (не решение) и выберите свойства. Должна появиться новая вкладка со всеми свойствами вашего проекта. Убедитесь, что вы находитесь в настройках сборки на новой вкладке. Поскольку вы хотите просмотреть настройки отладки, выберите отладку в раскрывающемся списке «Конфигурация». Установите флажок Оптимизировать код, сохраните и перестройте.   -  person Conduit    schedule 16.02.2016
comment
Не забудьте отключить это после того, как вы определили, является ли это причиной. Оптимизированный код не гарантирует, что он будет выполняться так же, как вы его написали, даже если вы получите тот же результат (за исключением того, что он будет быстрее/меньше). Это делает отладку практически невозможной;)   -  person Conduit    schedule 16.02.2016
comment
Я искал везде, но в свойствах нет вкладки «Сборка». Есть C/C++, Linker и т.д., но нет вкладки Build.   -  person LethalJam    schedule 16.02.2016
comment
Хм... должно быть, неправильно помню. Я сейчас далеко от своего компьютера, но я осмотрюсь, когда вернусь домой. Какую лицензию/версию VS вы используете?   -  person Conduit    schedule 16.02.2016
comment
Visual Studio Professional 2013, спасибо за помощь!   -  person LethalJam    schedule 16.02.2016
comment
Извините, я думал о свойствах проектов C#. Для проектов C++ параметры оптимизации можно найти в разделе Свойства конфигурации › C/C++ › Оптимизация. Вы можете переключаться между выпуском и отладкой, чтобы проверить различия — обязательно запишите свои изменения, чтобы вы могли отменить их.   -  person Conduit    schedule 17.02.2016
comment
Итак, я попытался изменить настройки оптимизации, но сначала это не сработало. Это противоречило двум другим настройкам. Это формат отладочной информации и базовые проверки во время выполнения. Когда я изменил только эти настройки, не меняя оптимизацию, частота кадров была увеличена до 150 кадров в секунду, благодаря чему отбраковка также улучшила частоту отладки. Я до сих пор понятия не имею, почему это работает, и если я должен оставить его таким образом.   -  person LethalJam    schedule 17.02.2016
comment
Когда вы компилируете сборку релиза, предполагается, что вся отладка завершена. Это означает, что вам не нужен способ присоединения отладчика к вашей программе во время ее выполнения. Это также означает, что компилятор может изменить способ выполнения программы, чтобы сделать ее более эффективной — процесс, известный как оптимизация. В качестве простого примера скажем, что вы кодируете строки int x = 5 * 4 + 6; x += 4;. При отладке каждая строка выполняется отдельно, но в оптимизированном коде ваш компилятор, вероятно, понимает, что он может просто сделать int x = 30;.   -  person Conduit    schedule 17.02.2016
comment
Поскольку ваш код намного эффективнее с этими измененными параметрами, мы знаем, что эффективность является результатом оптимизации, подобной приведенной выше. Компилятор нашел способ превратить ваш код в более эффективную, но эквивалентную версию самого себя. К сожалению, эффективный код больше не соответствует тому, на что вы смотрите, поэтому он бесполезен для отладки. Подумайте: в приведенном выше примере, когда оптимизированный код выполняет int x = 30;, в какой строке исходного кода он находится?   -  person Conduit    schedule 17.02.2016
comment
Так что нет - для вашего здравомыслия вы не должны держать это во время отладки. Теперь, когда вы знаете, что происходит, надеюсь, более низкий FPS во время отладки будет немного меньше давить на вас. Помните: все остальные, кто играет в вашу игру, будут работать над релизной копией/копией с высоким FPS!   -  person Conduit    schedule 17.02.2016
comment
Я вижу, но я до сих пор не совсем понимаю, как код, который значительно улучшает частоту кадров релиза, может снизить частоту кадров отладки. Функции пересечения SFML просто не оптимизированы для отладки?   -  person LethalJam    schedule 18.02.2016
comment
Из проведенных вами тестов может показаться, что без оптимизации накладные расходы на вычисление пересечений перевешивают преимущества отрисовки меньшего количества объектов, что приводит к снижению частоты кадров в отладочной сборке. Однако при оптимизации код, вычисляющий пересечения, становится более эффективным, что приводит к увеличению частоты кадров в релизе (или отладке, когда код оптимизирован).   -  person Conduit    schedule 18.02.2016
comment
Если вы получили SFML по обычным каналам (вероятно, так и есть, если только вы не создали библиотеки самостоятельно), я могу вас заверить, что он оптимизирован. Трудно сказать, почему это происходит, без дальнейшего тестирования. Поскольку вы изолировали проблему, я предполагаю, что не стоимость выполнения Rect<T>::intersect вызывает накладные расходы, а вызов функции.   -  person Conduit    schedule 18.02.2016
comment
Ах, хорошо, большое спасибо! Я полагаю, что общий смысл в том, что я должен оставить его таким, потому что это значительно улучшит опубликованный продукт. Еще раз спасибо, Кондуит!   -  person LethalJam    schedule 18.02.2016
comment
Не за что, рад помочь   -  person Conduit    schedule 21.02.2016


Ответы (1)


Итог долгой дискуссии в комментариях:

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

person Conduit    schedule 21.02.2016