Затраты на вычисления в C # - Использование геттеров / сеттеров и непосредственное изменение массивов и скорости приведения - PullRequest
1 голос
/ 11 июня 2010

Я собирался написать скучный пост, но здесь я его выкину:

Я пытаюсь подражать графическому старому стилю NES через XNA. Тем не менее, мой FPS медленный, пытается изменить 65K пикселей на кадр. Если я просто переберу все 65K пикселей и установлю их в произвольный цвет, я получу 64FPS. Код, который я сделал, чтобы посмотреть, какие цвета должны быть размещены, где, я получаю 1FPS.

Я думаю, это из-за моего объектно-ориентированного кода.

Прямо сейчас у меня есть вещи, разделенные на шесть классов, с геттерами / сеттерами. Я предполагаю, что я, по крайней мере, вызываю 360K геттеров на кадр, что, по-моему, является чрезмерной нагрузкой. Каждый класс содержит / и / или одномерные или двумерные массивы, содержащие пользовательские перечисления, int, Color или Vector2D, байты.

Что если я объединю все классы в один и получу доступ к содержимому каждого массива напрямую? Код выглядел бы беспорядочно и угробил бы концепции объектно-ориентированного кодирования, но скорость могла бы быть намного выше.

Меня также не беспокоит нарушение доступа, поскольку любые попытки получить / установить данные в массивах будут выполняться блоками. Например, вся запись в массивы будет выполняться до того, как к ним будут получены какие-либо данные.


Что касается приведения, я заявил, что я использую пользовательские перечисления, int, Color и Vector2D, байты. Какие типы данных наиболее быстро используются и доступны в .net Framework, XNA, XBox , C #? Я думаю, что постоянное приведение может быть причиной замедления здесь.

Кроме того, вместо математики для определения того, в какие индексы следует помещать данные, я использовал предварительно вычисленные таблицы поиска, поэтому мне не нужно использовать постоянное умножение, сложение, вычитание, деление на кадр. :)

Ответы [ 4 ]

4 голосов
/ 11 июня 2010

Это потрясающая презентация от GDC 2008, которую стоит прочитать, если вы являетесь разработчиком XNA.Это называется Понимание производительности XNA Framework .

Для вашей текущей архитектуры - вы недостаточно хорошо ее описали, чтобы дать определенный ответ - вы, вероятно, тоже делаетемного ненужных «мелочей» в тесной петле.Если бы мне пришлось угадывать, я бы предположил, что ваш текущий метод работает с кешем - вам нужно исправить макет данных.

В идеальном случае у вас должен быть хороший большой массив, как можно меньше типы значений (структуры, а не классы) и сильно встроенный цикл, который линейно помещает данные в него.

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

ОДНАКО - даже если оптимизировано - ваша текущая архитектура не работает.То, что вы делаете, противоречит тому, как работает современный графический процессор.Вы должны загружать свои спрайты в графический процессор и позволять ему объединять вашу сцену.

Если вы хотите манипулировать своими спрайтами на уровне пикселей (например, обмен паллетами, как вы упомянули), то вам следует использовать пиксельшейдеры.Процессор на 360 (и на ПК) быстрый, но графический процессор намного быстрее, когда вы делаете что-то подобное!

Образец Sprite Effects XNA - хорошее местоначать.

4 голосов
/ 11 июня 2010

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

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

1 голос
/ 11 июня 2010

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

EDIT

Хорошо, я думаю, что ваше решение может быть загрузить несколько спрайтов с разными цветами (спрайт в несколько пикселей) и использовать их повторно. Указать один и тот же спрайт быстрее, чем назначить разный цвет каждому пикселю, поскольку спрайт уже загружен в память

0 голосов
/ 11 июня 2010

Как и в случае любой проблемы с производительностью, вы должны профилировать приложение, чтобы определять узкие места, а не пытаться угадать.Я серьезно сомневаюсь, что геттеры и сеттеры являются корнем вашей проблемы.Компилятор почти всегда указывает на такие функции.Мне также любопытно, что ты имеешь против математики.Например, умножение двух целых чисел - одна из самых быстрых возможностей компьютера.

...