{"id":20655764,"url":"https://github.com/leonamtv/prime-sd","last_synced_at":"2026-05-30T04:31:22.588Z","repository":{"id":100983502,"uuid":"346351255","full_name":"leonamtv/prime-sd","owner":"leonamtv","description":"A comparison of prime numbers generation techniques.","archived":false,"fork":false,"pushed_at":"2021-04-04T01:41:14.000Z","size":149,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-17T11:15:21.593Z","etag":null,"topics":["concurrent","concurrent-programming","cpp","sequential"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leonamtv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-10T12:37:09.000Z","updated_at":"2021-04-04T01:41:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"8890834b-395e-4a33-95e7-aa66625aa2f2","html_url":"https://github.com/leonamtv/prime-sd","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonamtv%2Fprime-sd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonamtv%2Fprime-sd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonamtv%2Fprime-sd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonamtv%2Fprime-sd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leonamtv","download_url":"https://codeload.github.com/leonamtv/prime-sd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242762735,"owners_count":20181266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["concurrent","concurrent-programming","cpp","sequential"],"created_at":"2024-11-16T18:12:40.652Z","updated_at":"2025-12-24T04:33:03.894Z","avatar_url":"https://github.com/leonamtv.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Geração de primos\n\nEsse repositório contém o código para um trabalho da disciplina de Sistemas Distribuídos no CEFET-MG Timóteo. O código aqui presente, gera números primos indefinidamente (respeitando os limites do tamanho das variáveis) por **N** segundos de duas formas diferentes: uma abordagem sequencial e outra concorrente.\n\nA geração concorrente acontece da seguinte forma:\n\n1. Uma variável inteira armazena um número inicial.\n2. Cada thread incrementa esse valor e verifica se o valor incrementado é primo (utilizando **mutex** para travar as partes críticas). Cada uma das threads executam um loop infinito.\n3. Se o número for primo, uma variável de contagem de números primos é incrementada, também utilizando um **mutex** para garantir a consistência. Um segundo objeto **mutex** é utilizado para que não haja travamentos desnecessários nas outras threads que estejam utilizando um **lock** com o primeiro **mutex**. Nossos experimentos mostraram que dois **mutexes** permitem gerar mais primos do que apenas um.\n4. Esse processo é executado por **N** segundos.\n5. No final, a variável de contagem de primos é impressa no **stdout**.\n\nA geração concorrente acontece da seguinte forma:\n\n1. Uma variável inteira armazena um número inicial.\n2. Enquanto **N** segundos não se passarem, incrementamos o valor e verificamos se este é primo.\n3. Se o número for primo, uma variável de contagem de números primos é incrementada.\n4. No final, a variável de contagem de primos é impressa no **stdout**.\n\n## Estratégia de análise de desempenho\n\n* Gerar números primos sequencialmente por 5, 10, 20, 30, 40, 50, 60, 80, 100, 120 e 140 segundos, testando 10 vezes cada um dos tempos para que possamos tirar a média dos valores obtidos e diminuir a incerteza.\n* Gerar números primos concorrentemente por 5, 10, 20, 30, 40, 50, 60, 80, 100, 120 e 140 segundos com 2, 4 e 8 threads, testando 10 vezes cada um dos tempos para que possamos tirar a média dos valores obtidos e diminuir a incerteza.\n* Plotar tudo em um gráfico e analisar.\n\n## Coleta, preparação e visualização dos dados\n\nDois scripts foram feitos para isso: `data_collection.py` e `data_prep.py`.\n\n### Coleta de dados\n\nO script `data_collection.py` executa o software sequencial e paralelo várias vezes, com várias threads, por vários tempos pré definidos, armazena as saídas e salva em um arquivo json.\n\nA configuração da execução está no trecho abaixo do arquivo [data_collection.py](https://github.com/leonamtv/prime-sd/blob/master/data_collection.py):\n\n```python\ntentativas = 10\ntempos = [ 1, 2, 5, 10, 20, 30, 40, 50, 60, 80, 100, 120, 140 ]\nthreads = [ 2, 4, 8 ]\n```\n\nNo caso acima, o script irá executar o software sequencial por 1, 2, 5, 10, 20, 30, 40, 50, 60, 80, 100, 120 e 140 segundos, por 10 vezes cada e o software sequencial por 1, 2, 5, 10, 20, 30, 40, 50, 60, 80, 100, 120 e 140 segundos, por 10 vezes cada, com 2, 4 e 8 threads. O json é gerado no formato abaixo:\n\n```json\n{\n    \"sequential\": [\n        ...\n        {\n            \"tentativa\": 10,\n            \"tempo\": 100,\n            \"num_primes\": 809283\n        },\n        {\n            \"tentativa\": 10,\n            \"tempo\": 120,\n            \"num_primes\": 912152\n        },\n        {\n            \"tentativa\": 10,\n            \"tempo\": 140,\n            \"num_primes\": 1004348\n        }\n    ],\n    \"parallel\": [\n        {\n            \"tentativa\": 1,\n            \"tempo\": 1,\n            \"threads\": 2,\n            \"num_primes\": 90355\n        },\n        {\n            \"tentativa\": 1,\n            \"tempo\": 1,\n            \"threads\": 4,\n            \"num_primes\": 100800\n        },\n        {\n            \"tentativa\": 1,\n            \"tempo\": 1,\n            \"threads\": 8,\n            \"num_primes\": 105833\n        },\n        ...\n    ]\n}\n```\n\nEsse json é armazenado em uma pasta chamada `output/exec_\u003cdia\u003e_\u003cmes\u003e_\u003cano\u003e_\u003chora\u003e_\u003cminuto\u003e` com o nome `index.json`.\n\n### Preparação dos dados\n\nO script `data_prep.py` verifica qual a pasta mais recente contida na pasta `output` lê e faz parsing do `index.json` contido nesta, e gera um **csv** com os dados estruturados, prontos para serem plotados. O arquivo gerado é armazenado na pasta `data` com o nome `organized_data.csv`. Os dados ficam aproximadamente nesse formato:\n\n```csv\nindex,tipo,tentativa,tempo,threads,num_primes\n0,\"sequential\",1,1,0,69836\n1,\"sequential\",1,2,0,89857\n2,\"sequential\",1,5,0,138798\n3,\"sequential\",1,10,0,202830\n4,\"sequential\",1,20,0,303747\n5,\"sequential\",1,30,0,388620\n6,\"sequential\",1,40,0,462671\n7,\"sequential\",1,50,0,530729\n8,\"sequential\",1,60,0,593656\n9,\"sequential\",1,80,0,708913,\n...\n130,\"parallel\",1,1,2,90355\n131,\"parallel\",1,1,4,100800\n132,\"parallel\",1,1,8,105833\n133,\"parallel\",1,2,2,116530\n134,\"parallel\",1,2,4,131092\n135,\"parallel\",1,2,8,131589\n136,\"parallel\",1,5,2,172604\n137,\"parallel\",1,5,4,190863\n138,\"parallel\",1,5,8,199855\n139,\"parallel\",1,10,2,251952\n140,\"parallel\",1,10,4,275260\n141,\"parallel\",1,10,8,290153\n142,\"parallel\",1,20,2,378487\n143,\"parallel\",1,20,4,416030\n...\n```\n\n### Visualização\n\nUtilizamos um **jupyter notebook** para visualizar os dados. Resolvemos ignorar o arquivo propositalmente, pois este era muito grande. Para guardar a referência ao código utilizado para visualização, exportamos o conteúdo do **notebook** para um arquivo **python** [neste link](https://github.com/leonamtv/prime-sd/blob/master/jupyter/aggregate_and_plot.py).\n\nEsse **notebook** lê o conteúdo do arquivo **csv** gerado no passo anterior para um **pandas dataframe**, ordena os dados e agrupa os dados. Agrupamos as amostras por tentativa, calculando a média dos primos gerados, e plotamos o gráfico.\n\n## Resultados\n\n\u003cp align='center'\u003e\n    \u003cimg src='fig/resultado_14_03_2021.png'\u003e\n\u003c/p\u003e\n\n## Autores\n\n[Leonam Teixeira de Vasconcelos](https://github.com/leonamtv)\n\n[André Marcelino de Souza Neves](https://github.com/AndreNeves97)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonamtv%2Fprime-sd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleonamtv%2Fprime-sd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonamtv%2Fprime-sd/lists"}