Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. /*
  2. *   Nome: Antonio Ricardo Alexandre Brasil 
  3.           Michelle Borges Botelho
  4.           Gustavo Grimaldi
  5.     Data: 03/07/2014
  6.     Objetivo: Implementar um algoritmo de geração e verificação de numeros primos
  7.               que realize uma comparação dessa verificação utilizando threads e no modo
  8.               serial.
  9. *
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <math.h>
  14. #include <time.h>
  15. #include <pthread.h>
  16.  
  17. // -------------- Cabeçalho
  18. #define TAM_LINHA 20000  // Define o tamanho da linha da matriz
  19. #define TAM_COLUNA 20000 // Define o tamanho da coluna da matriz
  20. #define LIMITE 29999     // Limite da geração dos numeros na matriz
  21. #define LMACRO 10000  // Macro bloco linha
  22. #define CMACRO 10000   // Macro bloco coluna
  23. #define NTHREADS 9      // Numero total de threads
  24. #define SEMENTE 10       // Semente do srand()
  25.  
  26. int macroC = 0;          // Utilizando para controlar o proximo macrobloco coluna inicio a ser atribuido a uma thread
  27. int macroL = 0;          // Utilizando para controlar o proximo macrobloco linha inicio a ser atribuido a uma thread
  28. int qtNumerosPrimos;     // Quantidade de numeros primos da matriz
  29. int matriz[TAM_LINHA][TAM_COLUNA];  // matriz
  30.  
  31. pthread_mutex_t mutex_soma, mutex_macro; // Controle das regiões
  32.  
  33. void geraPrimos(void) {
  34.     /*
  35.         Objetivo: gerar os numeros primos na matriz.
  36.         Matriz[X][X];
  37.     */
  38.     printf("Gerando numeros primos ...\n");
  39.     int i = 0, j = 0;
  40.     for(i = 0; i < TAM_LINHA; i++) {
  41.         for(j = 0; j < TAM_COLUNA; j++) {
  42.             matriz[i][j] = rand() % LIMITE;   // Atribui um numero aleatorio iniciando do 0 até LIMITE.
  43.         }
  44.     }
  45. }
  46.  
  47. int verificaPrimo(int num) {
  48.     /*
  49.         Objetivo: verificar se determinado numero é um numero primo.
  50.        
  51.     */
  52.     if (num == 2)
  53.         return 1;
  54.     if ((num % 2) == 0 || num < 2)
  55.         return 0;
  56.     int i = 3, raiz = (int)sqrt(num);  
  57.     while (i <= raiz){
  58.         if ((num % i) == 0)
  59.             return 0;
  60.         i+=2;
  61.     }
  62.  
  63.     return 1;
  64. }
  65.  
  66. void checaPrimos() {
  67.     /*
  68.         Objetivo: identificar numeros primos na matriz de forma serial.
  69.     */
  70.     printf("Verificando numeros primos sem thread...\n");
  71.     int i = 0, j = 0;
  72.     for(i = 0; i < TAM_LINHA; i++) {
  73.         for(j = 0; j < TAM_COLUNA; j++) {
  74.             if (verificaPrimo(matriz[i][j])) {
  75.                 qtNumerosPrimos ++;
  76.             }
  77.         }
  78.     }
  79.  
  80.  
  81.     printf("Quantidade primos com thread: %d\n", qtNumerosPrimos);
  82.    
  83. }
  84.  
  85. void semThread()
  86. {
  87.     /*
  88.         Objetivo:
  89.             Função principal. Nela contem a função checa primos que verifica de forma serial
  90.             os numeros primos e contabiliza a variavel quantidade de numeros primos.
  91.        
  92.     */
  93.     clock_t ti, tf;
  94.     ti = clock();
  95.     checaPrimos();
  96.     tf = clock();
  97.     printf("Tempo de verificacao sem thread: %lf\n", (float) (tf - ti) / CLOCKS_PER_SEC);
  98.    
  99. }
  100.  
  101. void proxMacro(int *lr, int *cr) {
  102.     /*
  103.         Objetivo: Determina o macrobloco a ser acessado pela thread.
  104.         Passando como parametros as linhas(linharesultante) e a coluna(colunaresultante).
  105.     */
  106.     int l, c;
  107.     if (macroL == 0 && macroC == 0) {
  108.         /*
  109.             Se for a primeira execução, logo o macro bloco limite a ser atribuido é o LMACRO e o CMACRO.
  110.         */
  111.         macroL = LMACRO;
  112.         macroC = CMACRO;
  113.         l = macroL;
  114.         c = macroC;
  115.         *lr = l;
  116.         *cr = c;
  117.         return;
  118.     }
  119.     /*
  120.         Como não é a primeira execução, o algoritmo verifica se ja chegou ao limite da coluna.
  121.         Se chegou eu adiciono mais LMACRO na linha e reseto para o inicio do macrobloco coluna.
  122.     */
  123.     if (macroC >= TAM_COLUNA) {
  124.         macroL += LMACRO;
  125.         macroC = CMACRO;
  126.     }
  127.     else {
  128.         macroC += CMACRO;
  129.     }
  130.     l = macroL;
  131.     c = macroC;
  132.     *lr = l;
  133.     *cr = c;
  134.     /*
  135.         Retorno os valores e finalizo a função.
  136.     */
  137. }
  138. void *contaPrimos(void* arg) {
  139.     /*
  140.         Objetivo: É a chamada "slave" é nessa função que as threads irão trabalhar.
  141.     */
  142.     int tid = (int)arg;
  143.     while (1) {
  144.         /*
  145.             Irá pegar macroblocos enquanto não chegar no limite da linha.
  146.         */
  147.         int i = 0, j = 0;
  148.         int lp = 0, cp = 0;
  149.         int temp_soma = 0;
  150.         /*
  151.             Controla a região que atribui os macroblocos a thread.
  152.         */
  153.         pthread_mutex_lock(&mutex_macro);
  154.         proxMacro(&lp, &cp);
  155.         pthread_mutex_unlock(&mutex_macro);
  156.         if (lp > TAM_LINHA)
  157.             return(NULL);
  158.        
  159.  
  160.         /*
  161.             Ele irá iniciar na coluna:
  162.                     LP - LMACRO
  163.                 LP: macrobloco linha da thread a ser trabalhada.
  164.                     CP - CMACRO
  165.                 CP: macrobloco coluna da thread a ser trabalhada.
  166.                
  167.         */
  168.  
  169.         for (i = (lp - LMACRO); i < lp; i++) {
  170.  
  171.             for (j = (cp - CMACRO); j < cp; j++) {
  172.  
  173.                 if (verificaPrimo(matriz[i][j])) {
  174.                     temp_soma++;
  175.                 }
  176.  
  177.             }
  178.  
  179.         }
  180.         /*
  181.             Faz o controle da região da soma.
  182.         */
  183.         pthread_mutex_lock(&mutex_soma);
  184.         qtNumerosPrimos += temp_soma;
  185.         pthread_mutex_unlock(&mutex_soma);
  186.     }
  187.     return(NULL);
  188. }
  189.  
  190.  
  191. void comThread() {
  192.     /*
  193.         Função "main" que irá chamar todas as outras funções da thread.
  194.     */
  195.     pthread_t threads[NTHREADS];
  196.     int i = 0;
  197.     clock_t ti, tf;
  198.     printf("Verificando numeros primos com %d thread(s)...\n", NTHREADS);
  199.     ti = clock();
  200.  
  201.     pthread_mutex_init(&mutex_soma, NULL);
  202.     pthread_mutex_init(&mutex_macro, NULL);
  203.    
  204.     for (i = 0; i < NTHREADS; i++){
  205.         pthread_create(&(threads[i]), NULL, contaPrimos, NULL);
  206.     }
  207.  
  208.     for (i = 0; i < NTHREADS; i++){
  209.         pthread_join(threads[i], NULL);
  210.        
  211.        
  212.     }
  213.     tf = clock();
  214.     printf("Quantidade primos com thread: %ld\n", qtNumerosPrimos);
  215.     printf("Tempo de verificacao com thread: %lf\n", (float)(tf - ti) / CLOCKS_PER_SEC);
  216.  
  217. }
  218.  
  219.  
  220. int main() {
  221.    
  222.     srand(SEMENTE);
  223.  
  224.     geraPrimos();
  225.    
  226.     semThread();
  227.  
  228.     qtNumerosPrimos = 0;
  229.    
  230.     comThread();
  231.  
  232.     system("pause");
  233. }