Pular para o conteúdo principal
Basicamente, há três maneiras de usar o multiprocessamento com o ABBYY FineReader Engine: Por um lado, você pode usar um objeto Engine, definindo a propriedade MultiProcessingParams do objeto Engine com os valores adequados. O ABBYY FineReader Engine oferece suporte a dois objetos diferentes que fornecem multiprocessamento a partir de uma única instância do Engine. São eles: o objeto FRDocument (consulte Processamento com o objeto FRDocument) e o objeto BatchProcessor (consulte Processamento usando o Batch Processor). Por outro lado, você pode carregar várias instâncias do Engine como servidores fora do processo por meio de COM (usando o objeto OutprocLoader) e usar cada instância em seu próprio processo. Consulte Processamento usando um pool de Engines.
Considere que o processamento paralelo exige mais RAM do que o processamento sequencial. A recomendação geral para uma estação de trabalho é de 350 MB * (número de núcleos) + 450 MB de RAM; para documentos em árabe ou em idiomas CJK, a recomendação é de 850 MB * (número de núcleos) + 750 MB de RAM.

Cenários de uso

Partiremos do pressuposto de que você está processando uma grande quantidade de documentos. No entanto, também é necessário considerar os resultados que você precisa obter e escolher a melhor abordagem para implementar sua tarefa. Os cenários a considerar são:
  • Conversão de documentos com várias páginas e um grande número de páginas. Isso geralmente significa processar livros, relatórios longos, etc. Nesse caso, você pode reconhecer as páginas do documento em paralelo, depois realizar a síntese no processo principal e exportar em paralelo novamente. Também é possível, ao utilizar um pool de Engines, processar vários documentos de múltiplas páginas simultaneamente, mas o consumo de memória pode ser muito alto e até causar erros de “falta de memória”.
  • Conversão de uma grande quantidade de documentos de uma única página. É o caso quando você processa faturas, contratos, cartas, etc. O processamento paralelo é mais simples para essa situação, pois documentos de uma única página não dependem uns dos outros e não exigem grandes quantidades de memória ao mesmo tempo.
  • Processamento de uma grande quantidade de imagens para buscar informações específicas nelas, ou para trabalhar com os resultados de reconhecimento de alguma outra forma. Pode ser que você não precise converter a maioria delas para um formato editável, portanto a velocidade de síntese e exportação não é um problema. A operação que será executada em múltiplos processos é a iteração pelos blocos de layout e o acesso aos resultados de reconhecimento para blocos de texto.
Se você deseja usar o processamento paralelo para exportação, tenha em mente que esse recurso é compatível apenas com a exportação para PDF (exceto no modo TextOnly) e com os formatos PPTX.

Recomendações e restrições

  • Para o processamento paralelo de documentos com várias páginas, recomendamos o uso do FRDocument. É a forma de multiprocessamento mais fácil de implementar, pois não é necessário implementar interfaces adicionais.
    A abertura, o pré-processamento, a análise e o reconhecimento são realizados em paralelo; a síntese do documento é realizada sequencialmente no processo principal e, em seguida, a exportação para PDF (exceto no modo TextOnly) e os formatos PPTX são realizados em paralelo.
  • Para processar muitos documentos de uma página recebidos de alguma fonte (como um scanner), recomendamos o BatchProcessor.
    A vantagem desse método é que ele pode ser usado quando não se sabe antecipadamente o número de documentos — eles podem ser de tipos diferentes e precisam ser processados à medida que chegam. A desvantagem é que ele exige mais esforço de implementação: é necessário implementar interfaces para um adaptador de arquivo e uma fonte de imagens personalizada.
    Todos os estágios de processamento são realizados em paralelo porque, no caso de documentos de uma página, a síntese de página e documento é realizada separadamente para cada página.
A exportação paralela não é compatível com os cenários que utilizam o Batch Processor.
  • Para realizar o processamento completo de muitos documentos de uma página em paralelo, você pode usar um pool de Engines carregados fora do processo por meio de COM. Esse método é o mais eficiente em termos de velocidade e elimina automaticamente todas as dificuldades relacionadas ao multithreading: todas as operações com os objetos do ABBYY FineReader Engine são serializadas por meio de COM. No entanto, ele apresenta algumas limitações:
  • devido ao uso de COM, é necessário registrar o FREngine.dll;
  • se o código estiver escrito em C++, trabalhar com COM exige mais codificação de rotina do que, por exemplo, em C#;
  • nesse caso, o processamento ocorre em outro processo, portanto não é possível abrir imagens da memória, e a iteração dos resultados de reconhecimento leva mais tempo porque cada solicitação precisa ser transmitida para outro processo e de volta;
  • por fim, carregar várias instâncias do Engine implica maior consumo de memória — especialmente porque, nesse caso, todos os estágios de processamento são realizados em paralelo, e várias operações de síntese simultâneas podem ocorrer ao mesmo tempo, consumindo ainda mais memória.
  • Para capturar e tratar os eventos ocorridos durante o processamento paralelo, você pode usar a interface IParallelProcessingCallback. Essa interface pode ser muito útil para gerenciar situações problemáticas. Por exemplo, quando ocorre um erro de timeout, a interface IParallelProcessingCallback oferece diversas soluções para o problema de acordo com as preferências do usuário. Para mais informações, consulte IParallelProcessingCallback::OnWaitIntervalExceeded.
Os eventos ocorridos durante o processamento paralelo de uma página são convertidos em eventos de um documento inteiro.

Resultados dos testes de desempenho

Na tabela abaixo são apresentados os resultados dos testes de desempenho.
<br />Documentos de uma páginaUm documento de múltiplas páginasPesquisa nos resultados sem exportação
Processamento sequencial605187
Processamento com FRDocument4111757
Processamento com FRDocument (com PageFlushingPolicy = PFP_KeepInMemory)5514182
Processamento usando Batch Processor99115294
Processamento usando um pool de Engines16510102
O processador da máquina de teste é Intel® Core™ i5-4440 (3,10 GHz, 4 núcleos físicos), 8 GB de RAM, com 4 processos executados simultaneamente. O desempenho foi testado em 300 imagens em inglês, com as configurações do perfil predefinido DocumentArchiving_Speed. Os números na tabela representam páginas processadas por minuto. Nos cenários “documentos de uma página” e “um documento de múltiplas páginas”, os documentos são exportados para o formato PDF.

Processamento com o objeto FRDocument

O número de processos a serem executados é detectado automaticamente com base no número de núcleos de CPU físicos ou lógicos disponíveis, no número de núcleos de CPU livres disponíveis na licença e no número de páginas do documento. Para ativar o modo de multiprocessamento, siga estas etapas:
  1. Defina o valor da propriedade MultiProcessingMode do subobjeto MultiProcessingParams do objeto Engine. O processamento paralelo será utilizado se essa propriedade estiver definida como MPM_Parallel ou MPM_Auto, e tanto o número de páginas do documento quanto o número de núcleos de CPU disponíveis forem maiores que um.
  2. Ajuste o número de processos a serem executados usando a propriedade RecognitionProcessesCount e especifique os valores das demais propriedades, se necessário.
Após configurar as definições de multiprocessamento, você pode usar o procedimento padrão de trabalho com o FRDocument. O ABBYY FineReader Engine iniciará automaticamente vários processos de reconhecimento quando você chamar um dos seguintes métodos do objeto FRDocument: Para cada página do documento, uma nova tarefa de processamento é criada e atribuída a um dos processos de reconhecimento. Quando um processo de reconhecimento conclui a tarefa, ele recebe a próxima tarefa de processamento. Esse ciclo se repete até que todas as tarefas sejam concluídas.
// Criar o documento
FREngine.IFRDocument document = engine.CreateFRDocument();
// Adicionar páginas ao documento
for( int index = 0; index < filesNumber; index++ ) {
    string imagePath = filePaths[index];
    document.AddImageFile( imagePath, null, null );
}
// Configurar os parâmetros de multiprocessamento
engine.MultiProcessingParams.MultiProcessingMode = FREngine.MultiProcessingModeEnum.MPM_Parallel;
engine.MultiProcessingParams.RecognitionProcessesCount = coresNumber;
// Criar e configurar os parâmetros de processamento do documento
FREngine.IDocumentProcessingParams documentProcessingParams = engine.CreateDocumentProcessingParams();
...
// Processar o documento
document.Process( documentProcessingParams );
// Sintetizar e exportar o documento normalmente, trabalhar com os resultados, etc.
...
O pacote de distribuição do ABBYY FineReader Engine inclui a ferramenta de demonstração MultiProcessingRecognition, que demonstra o ganho de velocidade ao utilizar o reconhecimento com multiprocessamento com o objeto FRDocument e contém uma implementação que pode ser usada como ponto de partida para o desenvolvimento da sua própria aplicação.

Processamento usando o Batch Processor

Quando o Batch Processor é inicializado, os processos de reconhecimento assíncronos são invocados e configurados. Em seguida, o processor obtém arquivos de imagem de uma fonte de imagens personalizada. Para cada página do arquivo de imagem, uma nova tarefa de processamento é criada e passada para um dos processos de reconhecimento. Se todas as tarefas de um arquivo tiverem sido enviadas para processamento, mas nem todos os processos de reconhecimento estiverem ocupados, o próximo arquivo de imagem da fila de imagens da fonte é obtido e enviado para processamento. Isso ocorre até que a primeira página de imagem seja convertida e retornada ao usuário. As páginas são retornadas ao usuário na ordem em que foram obtidas da fonte de imagens. Para organizar o multiprocessamento com o Batch Processor, siga estas etapas:
  1. Implemente as interfaces IImageSource e IFileAdapter, que fornecem acesso à fonte de imagens e aos arquivos nela contidos.
  2. [opcional] Implemente a interface IAsyncProcessingCallback para gerenciar o processamento. Os métodos dessa interface permitem tratar erros e/ou cancelar o processamento.
  3. [opcional] Configure o multiprocessamento usando o subobjeto MultiProcessingParams do objeto Engine. Observe que não é necessário definir a propriedade MultiProcessingMode, pois o processamento paralelo é usado por padrão ao trabalhar com o Batch Processor. Ajuste o número de processos a serem executados usando a propriedade RecognitionProcessesCount e especifique os valores das demais propriedades, se necessário.
  4. Chame o método CreateBatchProcessor do objeto Engine para obter o objeto BatchProcessor.
  5. Chame o método Start desse objeto para inicializar o processor e invocar os processos de reconhecimento assíncronos. É possível especificar a fonte de imagens e passar as referências à interface IAsyncProcessingCallback e aos objetos de parâmetros na chamada a esse método.
  6. Chame o método GetNextProcessedPage em um loop até que ele retorne 0, o que indica que não há mais imagens na fonte e todas as imagens processadas foram retornadas ao usuário.
A página retornada pelo método GetNextProcessedPage existe até a próxima chamada desse método. Portanto, se você quiser salvar essa página, deverá fazê-lo usando os métodos do objeto FRPage ou adicioná-la a um documento existente usando o método IFRDocument::AddPage ANTES da próxima chamada do método GetNextProcessedPage.
// Criar o Batch Processor
FREngine.IBatchProcessor batchProcessor = engine.CreateBatchProcessor();
// Configurar os parâmetros de multiprocessamento
engine.MultiProcessingParams.RecognitionProcessesCount = coresNumber;
// Inicializar o processor
FREngine.IImageSource imageSource = new CImageSource; // a classe é implementada pelo usuário
batchProcessor.Start( imageSource, null, null, null );
// Iniciar o processamento
while( true ) {
 FREngine.IFRPage page = batchProcessor.GetNextProcessedPage();
 if( page == null ) {
  break; // não há mais páginas, fim do trabalho
 }
 // fazer algo com a página
 page.Synthesize( null );
 page.Export("D:\\sample.pdf", FREngine.FileExportFormatEnum.FEF_PDF, null);
}
O pacote de distribuição do ABBYY FineReader Engine inclui o exemplo BatchProcessing, que demonstra como usar o Batch Processor, e a ferramenta de demonstração BatchProcessingRecognition, que mostra o ganho de velocidade ao utilizar o reconhecimento com multiprocessamento com o Batch Processor.

Processamento usando um pool de Engines

Neste cenário de multiprocessamento, você utiliza várias instâncias do Engine carregadas fora do processo. Dentro de cada thread de trabalho, o procedimento pode ser quase o mesmo que para o processamento em uma única thread. No entanto, é recomendável implementar uma fonte de imagem personalizada que distribua as imagens entre as threads, usando algum tipo de objeto de sincronização para garantir que cada imagem seja processada uma única vez. Para carregar o objeto Engine fora do processo, utilize o objeto OutprocLoader, que implementa a interface IEngineLoader. Ao utilizá-lo com contas especiais, podem ser necessárias permissões para executar o OutprocLoader nessas contas.
// Para cada thread, crie um objeto OutprocLoader separado e carregue uma instância do Engine
IEngineLoader engineLoader = new FREngine.OutprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, LicensePath, LicensePassword, "", "", false );
// Obtivemos o Engine em um processo separado
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload(); // Podemos descarregá-lo quando não for mais necessário
 engineLoader = null;
 GC.Collect();
 GC.WaitForPendingFinalizers();
}
Além disso, você pode gerenciar a prioridade de um host process e controlar se ele está ativo usando a interface IHostProcessControl.
  • As permissões de conta podem ser configuradas usando o utilitário DCOM Config (digite DCOMCNFG na linha de comando ou selecione Painel de Controle > Ferramentas Administrativas > Serviços de Componentes). Na árvore do console, localize a pasta Serviços de Componentes > Computadores > Meu Computador > Configuração DCOM, clique com o botão direito em ABBYY FineReader Engine 12.5 Loader (Local Server) e clique em Properties. Uma caixa de diálogo será aberta. Clique na guia Segurança. Em Permissões de Inicialização, clique em Personalizar e, em seguida, clique em Editar para especificar as contas que podem iniciar o aplicativo.
Observe que, em um sistema operacional de 64 bits, o aplicativo DCOM registrado está disponível no console MMC de 32 bits, que pode ser executado usando a seguinte linha de comando:
"mmc comexp.msc /32"
  • Para registrar o FREngine.dll ao instalar seu aplicativo em um computador do usuário final, utilize o utilitário regsvr32. Se você estiver em um sistema operacional de 64 bits, a versão de 64 bits do regsvr32 será executada por padrão. Use a seguinte linha de comando:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"
  • Ao implementar o Engine como um servidor fora do processo, especifique o modo sequencial de processamento de documentos definindo a propriedade MultiProcessingMode do objeto MultiProcessingParams como MPM_Sequential.
O pacote de distribuição do ABBYY FineReader Engine inclui o exemplo EnginesPool, que demonstra o ganho de velocidade ao usar um pool de Engines e fornece uma implementação pronta para uso, que pode servir como ponto de partida para sua própria aplicação. Consulte o código-fonte deste exemplo para obter detalhes sobre como implementar uma fonte de imagem personalizada, tratar exceções e controlar o uso dos núcleos de CPU.

Consulte também

FRDocument BatchProcessor MultiProcessingParams Iterando Páginas do Document Diferentes Formas de Carregar o Engine Object Usando o ABBYY FineReader Engine em Aplicações de Servidor Multithread