Este repositório contém a implementação de algoritmos de convolução de imagens utilizando técnicas de programação concorrente, em Python e C. O projeto foi desenvolvido como parte da disciplina de Programação Concorrente (2024/1), oferecida pelo Instituto de Computação da Universidade Federal do Rio de Janeiro (UFRJ).
A convolução é uma operação matemática essencial no processamento de imagens, responsável pela aplicação de filtros para a detecção de padrões, como em redes neurais convolucionais (CNNs). No entanto, o cálculo sequencial da convolução é computacionalmente custoso, especialmente para imagens de grandes dimensões. Assim, implementamos versões paralelas da convolução, utilizando tanto Python quanto C, a fim de comparar a eficiência e o desempenho entre as duas linguagens.
O projeto inclui as seguintes abordagens para a implementação concorrente da convolução:
- Python:
- Implementação concorrente usando processos com a biblioteca
multiprocessing
. - Implementação com a biblioteca Numba para paralelização otimizada com o compilador LLVM.
- Implementação concorrente usando processos com a biblioteca
- C:
- Implementação concorrente usando threads, com divisão em blocos para otimização de cache.
- Python - Divisão Dinâmica: Cada processo calcula a convolução de forma independente para cada pixel.
- Python - Divisão em Blocos: A imagem é dividida em blocos, e cada processo é responsável por um bloco.
- Numba: Implementação otimizada utilizando paralelização automática com
@jit
eprange
. - C - Divisão em Blocos: Semelhante à versão em Python, mas implementada em C, aproveitando melhor a gestão de memória e threads.
Foram criados testes automatizados para verificar a corretude e o desempenho das implementações. As imagens de teste utilizadas possuem dimensões:
- 333x333
- 500x500
- 1024x768
Além disso, realizamos testes de desempenho com diferentes quantidades de processos/threads (1, 3, 7, 20) para comparar o ganho de velocidade em relação à versão sequencial.
Os testes de desempenho mostraram que a implementação com Numba foi a mais eficiente, superando até mesmo a versão em C. A versão em C apresentou resultados significativamente mais rápidos do que o Python nativo, que foi em torno de 100 vezes mais lento.
Apesar das limitações do Python em termos de gerenciamento de threads (devido ao Global Interpreter Lock - GIL), a utilização da biblioteca Numba permitiu atingir uma performance comparável à linguagem C. Esta biblioteca se mostrou extremamente eficiente para algoritmos numéricos que necessitam de grande poder computacional.
- Python 3.x
- GCC para compilar o código em C
- Bibliotecas:
Numba
,multiprocessing
,numpy
,opencv-python
-
Execute o seguinte comando no terminal e escolha os modos:
python main.py <input_image> <output_image>
💡 Caso queira executar a rotina de teste embutida no projeto, que irá testar os códigos tanto em C quanto em Python, execute o seguinte comando:
python3 test.py
- Caso deseje usar a versão em C, basta compilar a main usando:
gcc -o main ./C/main.c ./C/convolution.c -lpthread -Wall
- E execute o seguinte comando:
./main <matriz.bin> <kernel.bin> <n_threads> <matriz_saida>
Atenção: Esta versão somente aceita arquivos binários de imagem e de kernel, o que é gerado pelo código na função image.py e kernel.py. Por conta disso, recomendamos seu uso apenas para comparação com sua versão em Python.