Доброго времени суток. Некоторое время назад наткнулся на интересную трёхмерную демонстрацию карты звёзд, в центре которой, естественно, Солнце. Эта работа занимательна многим, например, как 2 миллиона трёхмерных координат передаются по сети, но меня заинтересовала больше частота кадров от 40 до 60 в минуту, причём минимальный порог она достигала только при максимально отдалении.
2 миллиона точек это немного, тем более для графического процессора, но так как в последнее время занимаясь разного рода визуализацией на canvas, слово частота и количество элементов воспринимаются довольно остро. Одна из таких работ по визуализации, это отображение амплитуды колебаний звука на определённых частотах в виде изменяющихся в размере, положении и цвете трёхмерных объектов. «Движок» для универсальной работы с отображением объектов собственный и, что странно, узкое место в нём не мои функции просчёта проекций из трёхмерного пространства на экран, а «родные» для canvas функции выделения области и её заполнения (больше 2 тысяч полигонов при шестидесяти кадрах в секунду он выводить не может).
Используются методы: beginPath, lineTo, fill.
Все из них наверняка исполняются на ЦП (хотя можно было бы заполнением и на ГП заниматься, правда только при большом количестве необходимых к заливке областей, объединяя их, иначе скорость обмена данными между памятью и памятью ГП может стать узким местом).
Вернёмся к демонстрации.
Вспомнив о ней совсем недавно, решил реализовать нечто подобное примеру, в котором каждая звезда является неизменной в размерах точкой (пикселем).
Программа:
Запись координат точек велась в двухбайтный целочисленный одномерный массив, индексы которого по модулю 3 равные 0 соответствовали X, 1 — Y, 2 — Z. Запись координат точек на экране в такого же типа одномерный массив, короче в полтора раза.
Использование метода fillRect отмелось сразу, даже без тестирования. И за основу вывода были взяты getImageData / putImageData.
После некоторого времени отбрасывания всего и оставления только необходимого пришло время тестов. Начались они с тысячи точек, на что соответствующий счётчик показал любимые числа (60, 59). На увеличение до двух тысяч он никак не отреагировал. И так до 128 тысяч, потом Chrome начал потихоньку сбавлять обороты.
Надо сказать, что при развёртывании окна на весь экран (1920x1080), а не на половину, Chrome даже при отсутствии звёзд показывал 40 кадров в секунду (происходит это из-за «ручного» очищения imageData в каждом кадре).
Видимо, вышеуказанный код медленный и браузеры умеют заливать быстрее, но при использовании их умения придётся каждый раз создавать новый imageData, а это ещё медленнее.
(это узкое место, но как следует оно не обдумывалось)
Производительность:
Несмотря на то, что в браузере отечественной компании у которой «найдётся всё», движок тоже webkit, частота кадров при половине экрана и 256 тысячах элементов — 60 гц.
Все тесты. В тестах использовались браузеры:
1. Google Chrome 54.0.2840.99 m
2. Yandex Browser 16.10.1.1114
Таблица 1. Тесты производительности, при окне в половину экрана
Таблица 2. Тесты производительности, при окне во весь экран
Если немного подумать, то средний результат не такой уж ошеломляющий (это просто работа с памятью), но разница по скорости обработки подобных данных на ГП всего в десять раз, что кажется весьма незначительным.
2 миллиона точек это немного, тем более для графического процессора, но так как в последнее время занимаясь разного рода визуализацией на canvas, слово частота и количество элементов воспринимаются довольно остро. Одна из таких работ по визуализации, это отображение амплитуды колебаний звука на определённых частотах в виде изменяющихся в размере, положении и цвете трёхмерных объектов. «Движок» для универсальной работы с отображением объектов собственный и, что странно, узкое место в нём не мои функции просчёта проекций из трёхмерного пространства на экран, а «родные» для canvas функции выделения области и её заполнения (больше 2 тысяч полигонов при шестидесяти кадрах в секунду он выводить не может).
Используются методы: beginPath, lineTo, fill.
Все из них наверняка исполняются на ЦП (хотя можно было бы заполнением и на ГП заниматься, правда только при большом количестве необходимых к заливке областей, объединяя их, иначе скорость обмена данными между памятью и памятью ГП может стать узким местом).
Вернёмся к демонстрации.
Вспомнив о ней совсем недавно, решил реализовать нечто подобное примеру, в котором каждая звезда является неизменной в размерах точкой (пикселем).
Программа:
Запись координат точек велась в двухбайтный целочисленный одномерный массив, индексы которого по модулю 3 равные 0 соответствовали X, 1 — Y, 2 — Z. Запись координат точек на экране в такого же типа одномерный массив, короче в полтора раза.
Использование метода fillRect отмелось сразу, даже без тестирования. И за основу вывода были взяты getImageData / putImageData.
После некоторого времени отбрасывания всего и оставления только необходимого пришло время тестов. Начались они с тысячи точек, на что соответствующий счётчик показал любимые числа (60, 59). На увеличение до двух тысяч он никак не отреагировал. И так до 128 тысяч, потом Chrome начал потихоньку сбавлять обороты.
Надо сказать, что при развёртывании окна на весь экран (1920x1080), а не на половину, Chrome даже при отсутствии звёзд показывал 40 кадров в секунду (происходит это из-за «ручного» очищения imageData в каждом кадре).
var data = IMGD.data; // IMGD получен с помощью метода getImageData
var len = data.length;
var color = 0, alpha = 255; // поскольку цвет заливки чёрный (rgb(0,0,0))
// то и поместим его в в одну переменную
// в imageData цвет точки задаётся четырьмя байтами (rgba)
// для задания прозрачности используем alpha
for(var i=0; i<len; i+=4) {
data[i] = data[i+1] = data[i+2] = color;
data[i+3] = alpha;
}
Видимо, вышеуказанный код медленный и браузеры умеют заливать быстрее, но при использовании их умения придётся каждый раз создавать новый imageData, а это ещё медленнее.
(это узкое место, но как следует оно не обдумывалось)
Производительность:
Несмотря на то, что в браузере отечественной компании у которой «найдётся всё», движок тоже webkit, частота кадров при половине экрана и 256 тысячах элементов — 60 гц.
Все тесты. В тестах использовались браузеры:
1. Google Chrome 54.0.2840.99 m
2. Yandex Browser 16.10.1.1114
Количество элементов (тыс.) | Chrome | Yandex браузер |
128 | 60 | 60 |
256 | 50 | 60 |
512 | 35 | 45 |
1024 | 22 | 27 |
Таблица 1. Тесты производительности, при окне в половину экрана
Количество элементов (тыс.) | Chrome | Yandex браузер |
128 | 32 | 60 |
256 | 28 | 47 |
512 | 22 | 34 |
1024 | 15 | 22 |
Таблица 2. Тесты производительности, при окне во весь экран
Если немного подумать, то средний результат не такой уж ошеломляющий (это просто работа с памятью), но разница по скорости обработки подобных данных на ГП всего в десять раз, что кажется весьма незначительным.