ajuste de memória e desempenho
🔗requisitos de memória
Processar uma imagem RAW no darktable requer uma grande quantidade de memória do sistema. Um cálculo simples deixa isso claro: para uma imagem de 20 megapixels, o darktable requer uma célula de ponto flutuante de 4x32 bits para armazenar cada pixel, o que significa que cada imagem completa desse tamanho exigirá aproximadamente 300 MB de memória apenas para armazenar os dados da imagem. Para realmente processar esta imagem em um determinado módulo, o darktable precisa de pelo menos dois buffers (entrada e saída) desse tamanho, com módulos mais complexos potencialmente exigindo vários buffers adicionais para dados intermediários. Sem otimização adicional, qualquer coisa entre 600 MB e 3 GB de memória pode ser necessária para armazenar e processar dados de imagem enquanto o pixelpipe é executado. Além disso, está o segmento de código do darktable, o código e os dados de quaisquer bibliotecas de sistema vinculadas dinamicamente, bem como outros buffers que o darktable usa para armazenar estados intermediários (cache) para acesso rápido durante o trabalho interativo.
Em resumo, o darktable requer pelo menos 4 GB de RAM física mais 4 a 8 GB de espaço de troca adicional para ser executado, mas terá um desempenho melhor quanto mais memória você tiver.
Além de serem executados em sua CPU, muitos módulos darktable também possuem implementações OpenCL que podem aproveitar ao máximo o processamento paralelo oferecido por sua placa gráfica (GPU). Da mesma forma, quanto mais memória GPU você tiver, melhor será o desempenho da darktable.
🔗mosaico
Se o darktable não tiver memória suficiente para processar a imagem inteira de uma só vez, os módulos podem optar por usar uma “estratégia de mosaico”, em que a imagem é dividida em partes menores (ladrilhos) que são processadas independentemente e, em seguida, costuradas novamente no fim. Embora isso permita que as imagens sejam processadas com uma pegada de memória muito menor, também apresenta algumas desvantagens:
-
o mosaico é sempre mais lento – às vezes até 10x mais lento, embora para alguns módulos a diferença seja insignificante,
-
o mosaico não é tecnicamente possível para alguns módulos devido à natureza dos algoritmos subjacentes.
Para a maioria dos sistemas, o mosaico provavelmente será usado apenas para exportações de imagem em tamanho real, com o trabalho interativo na sala escura sendo processado com mais eficiência. Para obter o melhor desempenho (e evitar os modos de mosaico), você deve executar o darktable juntamente com o menor número possível de outros aplicativos e configurar o darktable para usar o máximo possível da memória do sistema e da GPU.
🔗ajuste de performance
There are a number of configuration parameters that can help you to fine-tune your system’s performance. Some of these parameters are available in preferences > processing > CPU / memory and others need to be modified directly in darktable’s configuration file (found in $HOME/.config/darktable/darktablerc
).
Esta seção fornece algumas orientações sobre como ajustar essas configurações.
🔗como testar
Para determinar o quanto suas modificações melhoram (ou não) o desempenho do darktable, você precisará de uma ou mais imagens de amostra para testar e um método para avaliar a velocidade do pixelpipe.
Para imagens de amostra, é aconselhável usar alguns dos módulos mais intensivos, como difusão ou nitidez ou redução de ruído (perfilado). As exportações provavelmente terão tempos mais consistentes e comparáveis entre execuções de pixelpipe do que o trabalho interativo (e também forçarão mais o seu hardware).
Para obter informações sobre a criação de perfis, você deve iniciar o darktable de um terminal com o comando darktable -d opencl -d perf
. Se você deseja mais informações sobre a técnica de mosaico, você deve usar darktable -d opencl -d tiling -d perf
.
Cada vez que o pixelpipe é processado (quando você altera os parâmetros do módulo, amplia a imagem, desloca a imagem, exporta etc.) você verá (em sua sessão de terminal) o tempo total gasto no pixelpipe e o tempo gasto em cada um dos kernels OpenCL. O valor mais confiável é o tempo total gasto no pixelpipe e você deve usá-lo para avaliar suas alterações.
Nota: Os tempos fornecidos para cada módulo individual não são confiáveis ao executar o pixelpipe OpenCL de forma assíncrona (consulte modo assíncrono abaixo).
Para permitir um processamento eficiente com OpenCL, é essencial que a GPU seja mantida ocupada. Quaisquer interrupções ou um fluxo de dados paralisado aumentará o tempo total de processamento. Isso é especialmente importante para os pequenos buffers de imagem usados durante o trabalho interativo, que podem ser processados rapidamente por uma GPU rápida. No entanto, mesmo paradas de curto prazo do pixelpipe podem facilmente se tornar um gargalo.
Por outro lado, o desempenho do darktable durante as exportações de arquivos é mais ou menos governado apenas pela velocidade dos algoritmos e pela potência de sua GPU. As paradas de curto prazo não terão um efeito perceptível no tempo total de uma exportação.
🔗recursos do darktable
The “darktable resources” preference (in preferences > processing > CPU / memory) allows you to choose between four different approaches to allocating your system’s resources to darktable. Each of these options controls multiple individual parameters, which are defined independently in $HOME/.config/darktable/darktablerc
. You can amend any of these directly within your darktablerc file to tweak values for your selected resource level, though you cannot add your own custom resource level to the preferences drop-down.
Nota: O modo irrestrito realmente “leva tudo”. Esta pode parecer a melhor configuração a ser usada, mas, especialmente ao exportar imagens grandes com alta qualidade, o uso irrestrito de memória pode causar troca, o que pode levar ao desempenho prejudicado ou ao darktable ser silenciosamente eliminado pelo seu sistema operacional.
Cada uma das quatro opções de “recursos da darktable” é definida da seguinte forma:
resource_default=512 8 128 700
resource_large=700 16 128 900
resource_small=128 4 64 400
resource_unrestricted=16384 1024 128 900
Mais geralmente, elas podem ser representadas como resource_level=a b c d
onde a
- d
são definidos da seguinte forma:
- a. memória do sistema para processamento do módulo
- A quantidade máxima de memória do sistema disponibilizada para processamento do módulo. Valores mais baixos forçam os módulos que consomem muita memória a processar imagens com um número crescente de ladrilhos. Este número é uma fração da quantidade total de memória do sistema, dividida por 1024. Por exemplo, em um sistema com 16 GB de memória total do sistema, a quantidade atribuída por
resource_default
(em GB) é16 * 512 / 1024
, ou 8 GB de RAM do sistema. - b. tamanho mínimo do buffer de mosaico
- O tamanho mínimo de um único buffer de ladrilho, expresso de forma semelhante como uma fração da memória total do sistema. Por exemplo, em um sistema com 16 GB de memória total do sistema, a quantidade atribuída por
resource_default
(em GB) é16 * 8 / 1024
, ou 0,125 GB de RAM do sistema. Observe que essa configuração é em grande parte histórica e não tem mais uso prático – você é aconselhado a deixá-la em seu valor padrão. - c. memória cache de miniaturas
- A quantidade de memória a ser usada para o cache de miniaturas. Novamente, isso é expresso como uma fração da memória total do sistema e, em um sistema de 16 GB, a quantidade atribuída por
resource_default
é16 * 128 / 1024
, ou 2 GB de RAM do sistema. - d. memória OpenCL (GPU)
- A quantidade máxima de memória GPU disponibilizada para processamento do módulo. Assim como na memória do sistema, valores mais baixos forçarão os módulos que consomem muita memória a processar imagens com um número crescente de ladrilhos. A memória da GPU provavelmente também será usada por outros aplicativos em seu sistema. No entanto, em contraste com a memória do sistema, sua GPU não é capaz de aproveitar os arquivos de troca e é impossível para o darktable saber quanta memória está disponível em um determinado momento. Se este parâmetro for definido muito alto, o darktable pode ser forçado a retornar ao processamento da CPU (o que será significativamente mais lento, mas estável e com dados processados corretamente) ou o darktable poderá travar e até mesmo tornar seu sistema inutilizável. Por esse motivo, a fração do parâmetro de memória da GPU também inclui 400 MB extras de espaço livre na tentativa de evitar a alocação excessiva de memória. Por exemplo, em uma GPU com 6 GB de memória, o darktable usará aproximadamente
(6 - 0,6) * 700 / 1024
, ou 3,8 GB de RAM da GPU ao usar o nívelresource_default
.
Além dos níveis de recursos apresentados na interface do usuário, as seguintes opções podem ser definidas por meio da linha de comando (por exemplo, darktable --conf resourcelevel="notebook"
). Esses modos são projetados para depurar problemas de mosaico e testar o desempenho de sistemas comuns em máquinas de desenvolvimento maiores. As seguintes opções são fornecidas:
-
“mini” (1 GB de RAM, 2 MB de buffer único, 128 MB de cache de miniaturas, 200 MB de memória OpenCL)
-
“notebook” (4 GB de RAM, 32 MB de buffer único, 512 MB de cache de miniaturas, 1 GB de memória OpenCL)
-
“reference” (8 GB de RAM, 32 MB de buffer único, 512 MB de cache de miniaturas, 2 GB de memória OpenCL)
🔗ajuste do uso de memória da GPU
Se você quiser fazer uso máximo da memória da GPU para OpenCL, você tem três opções:
-
Escolha o nível de recurso “grande”. Para uma placa de 6 GB, isso usará aproximadamente 5 GB de memória da GPU, deixando 1 GB para o restante do sistema (recomendado).
-
Altere o darktablerc para aumentar o último número (a fração de memória OpenCL) para o nível de recurso selecionado. Por exemplo, aumentar a fração de memória OpenCL para 950 aumentaria a memória disponível em uma GPU de 6 GB para aproximadamente 5,3 GB (definitivamente não recomendável).
-
Set preferences > processing > OpenCL > use all device memory to “on”, which will use all of your device’s memory, less a 600MB headroom. Please see the section below for “per device setting” of headroom.
🔗OpenCL balanceado versus mosaico de CPU
Na maioria dos casos, executar um módulo de processamento em uma GPU de alta potência (o caminho de código OpenCL) é significativamente mais rápido do que executar o mesmo módulo usando o caminho de código da CPU. No entanto, muitos usuários têm CPUs multi-núcleo rápidas com uma grande quantidade de RAM do sistema, mas uma GPU com recursos significativamente inferiores (normalmente, gráficos integrados com pequenas quantidades de memória dedicada). O uso de código OpenCL nesses casos pode levar a um mosaico excessivo e geralmente é melhor executar um módulo sem mosaico usando o caminho de código da CPU do que tentar usar o OpenCL com mosaico pesado.
Ao processar o pipeline, o darktable tenta determinar qual modo será melhor para um determinado módulo, estimando as cargas de trabalho esperadas para os caminhos de código OpenCL e CPU. Na maioria dos casos, ele preferirá o caminho de código OpenCL, mesmo que isso signifique criar um mosaico da imagem, pois o OpenCL é normalmente muito mais rápido do que executar o código da CPU (geralmente até 10 vezes mais rápido se for um placa de vídeo dedicada).
Se a proporção de cargas de trabalho estimadas (CPU x GPU) for maior do que a dica vantajosa (veja abaixo), o darktable usará a CPU para processar esse módulo, caso contrário, usará a GPU.
🔗configuração OpenCL específica de dispositivo
As configurações padrão da darktable fornecem um desempenho de GPU razoável na maioria dos sistemas. No entanto, se você quiser tentar otimizar ainda mais as coisas, esta seção descreve os parâmetros de configuração relevantes (todos os quais são definidos em seu arquivo darktablerc).
A maioria das opções relacionadas ao OpenCL são gerenciadas com uma estratégia “por dispositivo”. O parâmetro de configuração para cada dispositivo se parece com:
cldevice_v5_nvidiacudaquadrortx4000=0 250 0 16 16 128 0 0 0.000 0.000 0.500
ou, mais genericamente
cldevice_versão_nomecanônico=a b c d e f g h i j k
Uma entrada será criada automaticamente no darktablerc para cada dispositivo recém-detectado quando você iniciar o darktable pela primeira vez, com o nome canônico correto do dispositivo e o número da versão. Os parâmetros a
- k
são definidos da seguinte forma e podem ser editados manualmente:
- a. evita atômico
- 1 = evita atômico; 0 = usa atômico (padrão)
- As operações atômicas no OpenCL são um método especial de sincronização de dados e são usadas apenas em alguns módulos. Infelizmente, alguns dos dispositivos AMD/ATI antigos são extremamente lentos no processamento atômico e, nestas placas, é melhor processar os módulos afetados na CPU em vez de aceitar uma codificação de GPU muito lenta. Portanto, defina este parâmetro para 1 se você experimentar processamento lento de módulos como sombras e realces, monocromático, contraste local ou mapa de tons global (obsoleto), ou se você obtiver travamentos intermitentes do sistema. Note que isto não deve afetar placas fabricadas a partir de 2015.
- b. micro nap
- padrão 250
- Em um caso ideal, você manterá sua GPU 100% ocupada ao processar o pixelpipe. No entanto, se sua GPU também precisar atualizar sua tela e o darktable estiver usando-a em 100%, pode não haver tempo suficiente para essa tarefa. Isso geralmente se manifestará como atualizações irregulares da interface ao deslocar a imagem, realizar um zoom ou ao mover controles deslizantes. Para resolver esse problema, o darktable pode adicionar pequenas pausas em seu processamento do pixelpipe para que a GPU possa recuperar o fôlego e realizar atividades relacionadas à interface gráfica. O parâmetro “micro nap” (micro soneca) controla a duração dessas pausas em microssegundos.
-
Em todos os sistemas atuais você está seguro com o valor padrão. Se você estiver usando vários dispositivos ou não estiver usando sua GPU discreta para desenhar na tela, esse valor poderá ser definido como 0 para todos os dispositivos que não sejam desktop, levando a um melhor desempenho.
- c. memória fixada
- 0 = desabilita transferência fixada (padrão); 1 = forçar transferência fixada
- Durante o mosaico, grandes quantidades de memória precisam ser transferidas entre o host e o dispositivo. Em alguns dispositivos, as transferências diretas de memória de e para uma região de memória de host arbitrária podem causar uma grande perda de desempenho. Isso é especialmente perceptível ao exportar imagens grandes em placas gráficas menores ou ao usar módulos mais recentes como difusão ou nitidez ou o modo laplaciano guiado no reconstrução de realce.
-
Não existe um método seguro ou regra geral para prever se esse parâmetro fornecerá ou não um benefício de desempenho, portanto, você terá que experimentar por si mesmo. No entanto, a chance de uma transferência fixada levar a uma melhoria é muito baixa se o seu cartão tiver sido fabricado depois de 2015.
- d. clroundup wh / e. clroundup ht
- Esses parâmetros devem ser deixados com seus valores padrão – testes não mostraram nenhum benefício em usar outros valores.
- f. número de manipuladores de eventos
- padrão 123
- Os manipuladores de eventos são usados pelo darktable para monitorar o sucesso/falha dos kernels e fornecer informações de criação de perfil, mesmo que o pixelpipe seja executado de forma assíncrona. O número de manipuladores de eventos é um recurso limitado do seu driver OpenCL – embora possam ser reciclados, há um número limitado que pode ser usado ao mesmo tempo. Infelizmente, não há como descobrir quais são os limites de recursos para um determinado dispositivo (isso se deve ao fato de o darktable usar a API OpenCL V.1.2 para suportar todas as plataformas), então o darktable usa uma estimativa muito conservadora de 128 por padrão. Na maioria dos dispositivos e drivers atuais, você pode esperar que um número de até 1024 seja seguro (com certeza se o seu driver/placa reportar OpenCL V.2.0 ou superior) e leve a um desempenho OpenCL ligeiramente melhor. Se o seu driver ficar sem manipuladores livres, você experimentará falhas nos kernels OpenCL com a mensagem de erro
CL_OUT_OF_RESOURCES
ou até mesmo travamentos ou congelamentos do sistema. (Se você estiver enfrentando esse problema, abra um problema no github) -
Um valor de 0 impedirá que o darktable use quaisquer manipuladores de eventos. Isso impedirá que o darktable monitore adequadamente o sucesso de seus kernels OpenCL, mas economiza alguma sobrecarga de driver, levando a um desempenho levemente melhor (menos de 5%). A consequência é que todas as falhas levarão a saídas distorcidas sem que o darktable perceba. Isso só é recomendado se você tiver certeza de que seu sistema é sólido como uma rocha.
- g. modo assíncrono
- 1 = usar modo assíncrono; 0 = não usar (padrão)
- Este sinalizador controla a frequência com que o darktable bloqueia o pixelpipe do OpenCL para obter um status de sucesso/falha dos kernels que foram executados. Para uma latência ideal, defina como 1, de forma que o darktable execute o pixelpipe de forma assíncrona e tente usar o mínimo de interrupções/eventos possível. Se você tiver erros de OpenCL, como kernels com falha, redefina o parâmetro como 0. Isto fará com que o darktable interrompa após cada módulo para que você possa isolar o problema mais facilmente. Problemas foram relatados com algumas placas AMD/ATI mais antigas (como a HD57xx) que podem produzir saída distorcida se este parâmetro for definido como 1. Em caso de dúvida, deixe o padrão 0.
- h. desabilitar dispositivo
- 0 = habilitar dispositivo; 1 = desabilitar dispositivo
- Se o darktable detectar um dispositivo com defeito, ele o marcará automaticamente como tal, definindo esse parâmetro como 1. Se você tiver um dispositivo que retorna muitos erros, poderá desativá-lo manualmente definindo este campo como 1. Se o darktable tiver desativado o dispositivo mas você tem certeza de que deve ser usado, você pode reativá-lo definindo este campo como 0.
i. reservado
- j. dica de vantagem
- Isso define a dica de vantagem descrita na seção OpenCL balanceado versus mosaico de CPU. Se você tiver uma placa gráfica rápida com muita memória, pode deixá-la com segurança em seu valor padrão de 0,000. No entanto, se você deseja adaptar esse número ao seu próprio sistema, deve usar o seguinte processo:
- Inicie o darktable com a opção de depuração do mosaico (
darktable -d tiling
) e comece a editar uma imagem na sala escura. Abra o módulo reconstrução de realce e use o método “laplaciano guiado”, definindo o “diâmetro de reconstrução” para um valor alto, garantindo que o mosaico não ocorra (verifique as informações de depuração em sua sessão de terminal enquanto ajusta o controle deslizante). - Verifique os tempos de execução deste módulo com o OpenCL ativado e desativado (executando
darktable -d perf
para examinar o desempenho). - Defina a “opção de dica de vantagem” para aproximadamente (tempo de execução da CPU / tempo de execução da GPU).
- k. fração de memória compartilhada
- Alguns dispositivos OpenCL não possuem memória dedicada, mas a compartilham com a CPU - o ARM da Apple é um exemplo, mas também dispositivos integrados de SOCs Intel, AMD ou ARM. Como queremos manter a memória do sistema disponível para cache ou caminhos de código da CPU, restringimos a quantidade de toda a memória usada para uma determinada fração. Portanto, com o padrão 0,5 e um computador Apple com 16 GB de RAM de sistema, o OpenCL seria capaz de usar 8 GB.
Nota: se o darktable detectar uma chave de configuração de dispositivo “com erros”, ela será reescrita para os valores padrão.
🔗configuração OpenCL específica de id
Uma segunda chave de configuração específica por dispositivo também é fornecida, que leva em consideração o nome do dispositivo e o ID do dispositivo (caso você tenha dois dispositivos idênticos). Neste caso, o nome de chave usual cldispositivo_versão_nomecanônico
é seguido por _idX
com X sendo o id do dispositivo. Por exemplo, se o dispositivo do exemplo acima foi referido como dispositivo 0, a segunda configuração (por padrão) seria cldevice_v5_quadrortx4000_id0=600
.
Esta chave de configuração atualmente tem apenas um único parâmetro definido:
- forced headroom (default 600)
- The amount of memory (in MB) that will not be used by darktable during OpenCL processing. This setting is only valid if you set preferences > processing > OpenCL > use all device memory to “on”.
-
Se você tiver certeza de que nenhum aplicativo (ou seu sistema operacional) usa o dispositivo específico, você pode definir este parâmetro como 0 para o dispositivo não usado para que o darktable use toda a memória desse dispositivo.
-
O padrão de 600 MB deve ser adequado para a maioria dos sistemas. Se você encontrar problemas de desempenho devido ao darktable voltar para a CPU, tente alterá-lo para 800 ou superior.
🔗outras chaves de configuração
As seguintes chaves de configuração adicionais também estão disponíveis no darktablerc:
- cldevice_version_canonicalname_building
- Esta opção é usada ao compilar kernels OpenCL e pode ser fornecida para ajuste de desempenho ou para contornar bugs. Você deve remover quaisquer kernels existentes para recompilá-los com as novas opções. Forneça uma string vazia para recompilar sem nenhuma opção. Remova a configuração inteiramente para recompilar com as opções padrão. O padrão é
-cl-fast-relaxed-math
para drivers nvidia, todas as outras placas não possuem esta opção do compilador definida. - A opção
-cl-fast-relaxed-math
melhora significativamente o desempenho, mas altera a matemática no código de processamento do módulo, possivelmente levando a resultados diferentes. Para implementações atuais da Intel, esse sinalizador do compilador leva a resultados visivelmente errados; em placas AMD, os resultados não são conclusivos. Algumas combinações de placa/driver são boas, outras não. Como os drivers AMD mudam constantemente, não recomendamos usá-lo em placas AMD. - opencl_mandatory_timeout
- padrão 400
- Se o darktable quiser fazer uso de qualquer dispositivo OpenCL, ele deverá reservá-lo para uso posterior. Se esse dispositivo for usado atualmente, o darktable irá esperar até opencl_mandatory_timeout * 5ms antes de fazer um fallback para a CPU. Aumente este valor se preferir usar OpenCL (porque sua placa é muito rápida e sua CPU não).