LoadPage в Shady очень медленный на Linux Mint - PullRequest
1 голос
/ 19 июня 2019

Я пытаюсь отобразить последовательность кадров, используя Shady, но у меня возникают трудности.Я смотрю на 25 кадров, охватывающих область 1080x1080 пикселей.Стимул - в оттенках серого, и я делаю линеаризацию яркости в автономном режиме, поэтому мне нужно только сохранить значение uint8 для каждого пикселя.Полная последовательность составляет около 29 МБ.Я определяю стимул как массив 3-D numpy [1080x1080x25] и сохраняю его на диск с помощью np.save ().Затем я загружаю его с помощью np.load ().

    try:
        yy = np.load(fname)
    except:
        print fname + ' does not exist'
        return

Этот шаг занимает около 20 мс.Насколько я понимаю, Shady имеет дело не со значениями яркости uint8, а с числами с плавающей точкой от 0 до 1. Таким образом, я преобразовываю его в массив с плавающей точкой и делю на 255.

yy = yy.astype(np.float)/255.0

Этот второй шаг занимает примерно260 мс, что уже не здорово (в идеале мне нужно загрузить стимул и подготовить его к презентации за 400 мс).Теперь я создаю список из 25 пустых массивов для использования в качестве параметра pages в классе Stimulus:

    pages = []
    for j in range(yy.shape[2]):
        pages.append(np.squeeze(yy[:, :, j]))

Это практически мгновенно.Но на следующем шаге я столкнулся с серьезными проблемами синхронизации.

if (self.sequence is None):
    self.sequence = self.wind.Stimulus(pages, 'sequence', multipage=True, anchor=Shady.LOCATION.UPPER_LEFT, position=[deltax, deltay], visible=False)
else:
    self.sequence.LoadPages(pages, visible=False)

Здесь я либо создаю объект Stimulus, либо обновляю его атрибут pages , если это не первая загружаемая последовательность.В любом случае, этот шаг занимает около 10 секунд, что примерно в 100 раз больше, чем я могу допустить в своем приложении.

Есть ли способ значительно ускорить это?Что я делаю неправильно?У меня довольно посредственная видеокарта на этой машине (Radeon Pro WX 4100), и если в этом проблема, я мог бы ее обновить, но я не хочу переживать, если это не поможет.

Ответы [ 2 ]

1 голос
/ 20 июня 2019

Основываясь на комментариях Jez, его тестах и ​​моих тестах, я предполагаю, что в некоторых конфигурациях (в моем случае Linux Mint 19 с Cinnamon и посредственной видеокартой AMD) плавание может быть намного медленнее, чем загрузка uint8.С uint8 поведение кажется одинаковым для всех конфигураций.Так что иди с uint8, если можешь.Поскольку это (я полагаю) отключит многое из того, что может сделать Shady с точки зрения гамма-коррекции и улучшения динамического диапазона, для некоторых это может быть ограничением.

0 голосов
/ 21 июня 2019

Shady может принимать значения uint8 пикселей как есть, чтобы вы могли вырезать свой код для масштабирования и преобразования типов. Конечно, вы теряете способность Shady улучшать динамический диапазон таким образом, но, похоже, у вас есть свои автономные решения для такого рода вещей. Если вы собираетесь использовать исключительно стимулы uint8, вы можете сэкономить немного усилий на обработке GPU, отключив сглаживание (установите .ditheringDenominator для World и Stimulus на 0 или отрицательное значение) .

Кажется, что смешные задержки в 10–15 секунд возникают из-за скомпилированного двоичного компонента «ускорителя» при передаче необработанных текстурных данных из ОЗУ на видеокарту. Проблема, по-видимому, (а) специфична для передачи данных текстуры с плавающей точкой, а не целочисленных данных, и (б) специфична для вашей видеокарты (поскольку вы сообщали, что проблема исчезла в той же системе, когда вы меняли карту NVidia ). Возможно, это также зависит от ОС или драйвера для старой видеокарты.

Обратите внимание, что вы также можете сократить время LoadPages() с 300–400 мс до примерно 40 мс, сократив количество операций numpy, которые должна выполнять Шейди. Сохраните ваши массивы как [страницы х строк х столбцов] вместо [строк х столбцов х страниц]. Относительно вашего существующего рабочего процесса это означает, что вы делаете yy = yy.transpose([2, 0, 1]) перед сохранением. Затем при загрузке не транспонировать обратно: просто разделить на axis=0, а затем squeeze крайнее левое измерение из каждой полученной страницы:

pages = [ page.squeeze(0) for page in numpy.split(yy, yy.shape[0], axis=0) ]

Таким образом, вы получите 25 представлений в исходном массиве, каждый которого представляет собой непрерывный блок памяти. В отличие от этого, если вы делаете это оригинальным способом [строки х столбцов х страниц], то независимо от того, используете ли вы разбиение и сжатие или исходный цикл срезания и сжатия, вы получите 25 не - непрерывные взгляды в исходную память, и этот факт рано или поздно настигнет вас - если не тогда, когда вы или Шейди конвертируете между числовыми форматами, то самое позднее, когда Шейди использует метод numpy .tostring для сериализации данных для передачи.

...