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
Há vários parâmetros de configuração que podem ajudá-lo a ajustar o desempenho do seu sistema. Alguns destes parâmetros estão disponíveis em preferências > processamento > cpu/gpu/memória e outros precisam ser modificados diretamente no arquivo de configuração do darktable (encontrado em $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
A preferência de “recursos do darktable” (em preferências > processamento > cpu/gpu/memória) permite que você escolha entre quatro abordagens diferentes para alocar recursos do seu sistema para darktable. Cada uma dessas opções controla vários parâmetros individuais, que são definidos independentemente em $HOME/.config/darktable/darktablerc
. Você pode alterar qualquer um deles diretamente em seu arquivo darktablerc para ajustar os valores para o nível de recurso selecionado, embora não possa adicionar seu próprio nível de recurso personalizado ao menu suspenso de preferências.
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 pode ser difícil para o darktable saber exatamente 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). 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,4) * 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.
-
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.
-
Defina preferências > processamento > cpu / gpu / memória > ajustar desempenho OpenCL para “tamanho da memória”, que usará toda a memória do seu dispositivo, menos um espaço de 400 MB. Consulte a seção abaixo para outras opções relacionadas a essa configuração.
🔗configuração OpenCL específica de dispositivo
As configurações padrão da darktable devem fornecer 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 partir do darktable 4.0, 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_v4_quadrortx4000=0 250 0 16 16 1024 0 0 0.017853
ou, mais genericamente
cldevice_versão_nomecanônico=a b c d e f g h i
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
- i
são definidos da seguinte forma e podem ser editados manualmente:
- a. evita atômico
- 1 = evita atômico; 0 = usa atômico
- 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. Nos sistemas atuais, você está bastante seguro com o valor padrão, mesmo para placas gráficas integradas. Se você estiver usando vários dispositivos ou não estiver usando sua GPU dedicada para desenhar na tela, esse valor poderá ser definido como 0 para o dispositivo não desktop.
- c. memória fixada
- 0 = usar interface para selecionar o modo; 1 = forçar transferência fixada; 2 = desabilita a 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 conta própria. Este modo também pode ser definido globalmente definindo a opção “ajustar performance do OpenCL” para “transferência de memória” (em preferências > processamento > cpu/gpu/memória), sendo que neste caso este parâmetro deve ser definido como 0. Caso contrário, você pode habilitá-lo/desabilitar em um nível de dispositivo usando este parâmetro.
- 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
- 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, 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 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. -
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 melhor desempenho. A consequência é que quaisquer falhas provavelmente 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
- 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 (o padrão). 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 0.
- i. benchmark
- Quando o darktable detectar um novo dispositivo em seu sistema, ele fará um pequeno benchmark e armazenará o resultado aqui. Você pode alterar isso de volta para 0 para forçar o darktable a refazer o benchmark, mas na maioria dos casos você não deve editar essa configuração.
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_v4_quadrortx4000_id0=400
.
Esta chave de configuração atualmente tem apenas um único parâmetro definido:
- espaço livre forçado (padrão 400)
- A quantidade de memória (em MB) que não será usada pelo darktable durante o processamento do OpenCL. Essa configuração só é válida se você definir preferências > processamento > ajustar desempenho OpenCL como “tamanho da memória”.
-
Se você definir este parâmetro para zero (
0
) então, na primeira execução de um pixelpipe, o darktable tentará determinar quanta memória GPU está realmente disponível e usa isso (com uma margem de segurança de 100MB) como a quantidade máxima de memória que o darktable usará, pelo restante da sua sessão. Isso geralmente é seguro, a menos que você inicie outros aplicativos (que usam uma quantidade razoável de memória da GPU) enquanto o darktable está em execução. Caso contrário, o uso dessa opção pode levar a erros de falta de memória, o que fará com que o darktable retorne à CPU, reduzindo significativamente o desempenho. Você pode desativar e ativar esta opção para solicitar que o darktable execute seu cálculo de memória novamente (no início da próxima execução do pixelpipe). Observe que existem problemas conhecidos com a auto-detecção de memória em drivers Nvidia mais novos, assim a auto-detecção deve ser usada com cuidado e por isso é desabilitada por padrão. -
Se você tiver certeza de que nenhum aplicativo (ou seu sistema operacional) usa o dispositivo específico, você pode definir este parâmetro como 1 para o dispositivo não usado para que o darktable use toda a memória desse dispositivo.
-
O padrão de 400 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 600 ou desabilitar o “ajuste para o tamanho da memória”.
🔗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
- opencl_synch_cache
- Se definido como “true”, este parâmetro forçará o darktable a buscar buffers de imagem de sua GPU após cada módulo e armazená-los em seu cache de pixelpipe. Esta é uma operação que consome recursos, mas pode fazer sentido dependendo de sua GPU (inclusive se a GPU for bastante lenta). Neste caso, o darktable pode, de fato, economizar algum tempo quando os parâmetros do módulo forem alterados, pois pode voltar a algum estado intermediário armazenado em cache e reprocessar apenas parte do pixelpipe. Em muitos casos, este parâmetro deve ser definido como “active module” (o padrão), que armazenará apenas em cache a entrada do módulo atualmente em foco.