darktable page lede image
darktable page lede image

Otimização de desempenho do OpenCL

10.2.7. Otimização de desempenho do OpenCL

Há alguns parâmetros em $HOME/.config/darktable/darktablerc que ajudam a realizar o ajuste fino do desempenho do OpenCL no seu sistema. O desempenho, neste contexto, significa principalmente a latência do darktable durante trabalho interativo, ou seja, quanto tempo o darktable demora para reprocessar a pixelpipe. Para um fluxo de trabalho confortável é essencial manter a latência baixa.

Para obter informação de profiling você inicia o darktable em um terminal com

darktable -d opencl -d perf

Depois de cada reprocessamento da pixelpipe - causado por mudança de parâmetro em um módulo, zoom, arrastar, etc - você verá o tempo total e o tempo gasto em cada um dos kernels do OpenCL. O valor mais confiável é o tempo total gato na pixelpipe. Note que os tempos dados para cada módulo individual não são confiáveis quando usando a pixelpipe OpenCL de maneira assíncrona (veja opencl_async_pixelpipe abaixo).

Para permitir um processamento rápido da pixelpipe com OpenCL é essencial manter a GPU ocupada. Qualquer interrupção ou fluxo de dados parado adicionará ao tempo total de processamento. Isto é especialmente importante para os pequenos buffers de imagem que precisamos usar durante trabalho intensivo. Eles podem ser processados rapidamente por uma GPU rápida. No entanto, mesmo paradas pequenas da pixelpipe podem facilmente se tornar um gargalo.

Por outro lado, o desempenho do darktable durante a exportação de arquivos é mais ou menos governado apenas pela velocidade dos algoritmos e pela potência de sua GPU. Paradas de curto prazo não terão efeito perceptível no tempo total de exportação.

o darktable vem com configurações default que devem resultar em bom desempenho de GPU na maioria dos sistemas. No entanto, se quiser mudá-las um pouco e tentar otimizar mais, aqui está uma descrição dos parâmetros relevantes de configuração.

opencl_async_pixelpipe

Esta flag controla quão frequentemente bloqueamos a pixelpipe OpenCL e obtemos um status de sucesso/falha de todos os kernels que estiverem rodando. Para latência ótima defina em TRUE, para que o darktable rode a pixelpipe assincronamente e tente usar tão poucas interrupções quanto possível. Se perceber erros do OpenCL, como kernels falhando, defina em FALSE. O darktable irá então interromper o processamento após cada módulo para que você possa mais facilmente isolar o problema. Houve problemas reportados com algumas placas antigas ATI/AMD, como a HD57xx, que pode produzir saída embaralhada quando este parâmetro é TRUE. Em dúvida, deixe no default, FALSE.

opencl_number_event_handles

manipuladores de eventos (event handlers) são usados para que possamos monitorar sucesso e falha de kernels e informação de profiling, mesmo que a pixelpipe rode assincronamente. O nero de manipuladores de evento é um recurso limitado do driver OpenCL. Claro que podemos reciclá-los, mas existe um número limitado que podemos usar ao mesmo tempo. Infelizmente, não há como saber qual é o limite de recursos; temos que adivinhar. Nosso valor default de 25 é bem conservador. Você pode querer tentar verificar se valores mais altos, como 100, melhoram o desempenho do OpenCL. Se seu driver ficar sem recursos, você perceberá kernels OpenCL falhando com código -5 (CL_OUT_OF_RESOURCES) ou mesmo travamentos de sistema; reduza novamente o número neste caso. Um valor de 0 impede que o darktable use qualquer manipulador de eventos. Isto previne o darktable de monitorar o sucesso de seus kernels OpenCL, mas retira um pouco da sobrecarga do driver. Como consequência, quaisquer falhas irão provavelmente levar a saída errada sem que o darktable perceba; só é recomendado se você tem certeza que seu sistema roda com muita solidez. Você também pode definir este parâmetro em -1, que significa que o darktable presumirá que não há restrições ao número de manipuladores de eventos; isto não é recomendado.

opencl_synch_cache

Este parâmetro, se definido em "true", forçará o darktable a buscar os buffers de imagem da sua GPU depois de cada mulo e armazená-los no cache da pixelpipe. Esta é uma operação que consome recursos, mas faz sentido dependendo da sua GPU (incluindo se sua GPU é lenta). Neste caso o darktable poderá de fato ganhar algum tempo quando os parâmetros do módulo forem mudados, porque pode voltar a um estado intermediário em cache e reprocessar somente parte da pixelpipe. Em muitos casos, este parâmetro deveria ser definido em "active module" (default), o que somente guardará em cache a entrada do módulo em foco.

opencl_micro_nap

Idealmente, você manteria sua GPU ocupada 100% do tempo de reprocessamento da pixelpipe. Isto seria bom. Por outro lado, sua GPU também seria necessária para realizar atualizações regulares na interface. Pode acontecer de não haver tempo suficiente sobrando para isso. A consequência seria uma reação com movimentos truncados/intermitentes da interface ao arrastar ou fazer zoom, ou ao mover deslizadores. O darktable pode adicionar pequenas pausas no processamento da pixelpipe para que a GPU possa fazer um pouco do trabalho relacionado à interface. O parâmetro opencl_micro_nap controla a duração dessas pausas em microssegundos. Você precisa experimentar para encontrar o valor ótimo para seu sistema. Valores de 0, 100, 500 e 1000 são bons pontos de partida. O default é 1000.

opencl_use_pinned_memory

Durante o ladrilhamento, uma grande quantidade de memória precisa ser transferida entre o host e o dispositivo. Em alguns dispositivos (AMD), transferência direta de memória de e para uma região arbitrária de memória do host pode acarretar uma grande queda de desempenho. Isto é particularmente perceptível ao exportar imagens grandes. Definir este parâmetro em TRUE diz o darktable para usar um tipo de buffer intermediário especial para a transferência de dados. Em alguns dispositivos, isto pode acelerar a exportação de imagens para grandes arquivos por um fator entre 2 e 3. Dispositivos e drivers NVIDIA e parecem usar uma técnica de transferência de memória mais eficiente, mesmo para regiões arbitrárias da memória. Como podem não resultar em ganho de desempenho e podem até produzir saída errada, opencl_use_pinned_memory deveria ser deixado em seu estado default FALSE para estes dispositivos.