SAM Example 6

From SoOS

Jump to: navigation, search

Contents

[edit] Description

[edit] Code

[edit] example6.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sam.h>
  4.  
  5. #include "bs.h"
  6. #include "conf.h"
  7.  
  8.  
  9. struct datast
  10. {
  11.   int index;
  12.   void *pdat;
  13.   int doit;
  14. };
  15.  
  16. int cmp1(utype a, utype b)
  17. {
  18.   if (a > b)
  19.     return 1;
  20.   else if (a < b)
  21.     return -1;
  22.   else
  23.     return 0;
  24. }
  25.  
  26. int cmp2(utype a, utype b)
  27. {
  28.   if (a < b)
  29.     return 1;
  30.   else if (a > b)
  31.     return -1;
  32.   else
  33.     return 0;
  34. }
  35.  
  36. void * worker_routine(void *args)
  37. {
  38.   SAM_t sam_context; /* Declare a SAM context variable */
  39.   void *myargs; /* Pointer to where the arguments are stored */
  40.   struct datast *data_arg; /* Pointer to the arguments of the function */
  41.   int *result; /* Pointer to the result (total) of the calculation */
  42.   SAM_pdif_t dif; /* The differential for the __SAM_ADDR__() macro*/
  43.   void *data;
  44.   int index;
  45.  
  46.   /* Start the execution of this worker thread */
  47.   /* Extract the SAM context and the arguments */
  48.   SAM_Execution_start(args, &sam_context, &myargs);
  49.  
  50.   /* Extract the arguments of the function */
  51.   data_arg = (struct datast *) myargs;
  52.   index = data_arg->index;
  53.   data = data_arg->pdat;
  54.  
  55.   if(data_arg->doit)
  56.     {
  57.       /* Declare the region as read by the worker thread */
  58.       SAM_Memory_speculative_read(sam_context, SAM_My_workid(sam_context), data);
  59.  
  60.       /* Prepare the memory region for speculative write and obtain the differential parameter */
  61.       dif = SAM_Memory_speculative_write_prepare(sam_context, data);
  62.  
  63.       bubbleSort(data, cmp1, NX, dif);
  64.     }
  65.  
  66.   SAM_Execution_finish(sam_context);
  67.  
  68.   result = (int *) malloc(sizeof(int));
  69.   *result = 0;
  70.  
  71.   return result;
  72. }
  73.  
  74. void fillArray(utype *A)
  75. {
  76.   int i;
  77.  
  78.   for(i=0; i < NX; i++)
  79.     {
  80.       A[i] = rand();
  81.     }
  82. }
  83.  
  84. int main()
  85. {
  86.   SAM_t sam_context; /* Declare a SAM context variable */
  87.   SAM_Workerid_t th[N]; /* For storing the worker threads ID's  */
  88.   int *result; /* Gets the result of the worker thread */
  89.   struct datast data_arg[N]; /* Pointer to the worker threads arguments */
  90.   utype *dat;
  91.   utype *ldat;
  92.   int i;
  93.   int j;
  94.   int n;
  95.   int next;
  96.   int sel;
  97.  
  98.   dat = malloc(NX * NY * sizeof(utype));
  99.   ldat = malloc(NX * sizeof(utype));
  100.  
  101.   for(i=0; i < NY; i++)
  102.     {
  103.       fillArray(&dat[i*NX]);
  104.     }
  105.  
  106.   fillArray(ldat);
  107.  
  108.   /* Initialize the SAM context */
  109.   SAM_Init(&sam_context);
  110.  
  111.  
  112.   /* Register a region and protect it */
  113.   for(i=0; i < NY; i++)
  114.     {
  115.       SAM_Memory_region_register(sam_context, &dat[i*NX], NX * sizeof(utype));
  116.       SAM_Memory_region_protect(sam_context, &dat[i*NX]);
  117.     }
  118.  
  119.   for(i=0; i < N; i++)
  120.     {
  121.       data_arg[i].index = i;
  122.       data_arg[i].pdat = &dat[i*NX];
  123.       data_arg[i].doit = 1;
  124.  
  125.       /* Create the worker threads running worker_routine  */
  126.       th[i] = SAM_Execution_create(sam_context, *worker_routine, (void *)(&data_arg[i]));
  127.     }
  128.  
  129.   bubbleSort(ldat, cmp2, NX, 0);
  130.   for(j=0; j < NX; j++)
  131.     {
  132.       ldat[j] = ldat[j] % (1024 + j);
  133.     }
  134.  
  135.   sel = rand() % NX;
  136.   sel = ldat[sel] % NY;
  137.  
  138.   printf("sel: %d\n", sel);
  139.  
  140.   for(i=0;i<N;i++)
  141.     {
  142.       if(i != sel)
  143. 	{
  144. 	  SAM_Execution_cancel(sam_context, th[i]);
  145. 	}
  146.     }
  147.  
  148.   result = (int *)SAM_Execution_join(sam_context, th[sel]);
  149.   free(result);
  150.  
  151.  
  152.   /* Release and unregister the memory region*/
  153.   for(i=0; i < NY; i++)
  154.     {
  155.       SAM_Memory_region_release(sam_context, &dat[i*NX]);
  156.       SAM_Memory_region_unregister(sam_context, &dat[i*NX]);
  157.     }
  158.  
  159.   /* Destroy the SAM context */
  160.   SAM_Destroy(&sam_context);
  161.  
  162.   for(i=0; i < NY; i++)
  163.     {
  164.       for(j=0; j < NX; j++)
  165. 	{
  166. 	  printf("(%d, %d) --> %d\n", i, j, dat[(i*NX)+j]);
  167. 	}
  168.     }
  169.  
  170.   free(dat);
  171.   free(ldat);
  172.  
  173.   return 0;
  174. }

[edit] conf.h

  1. #define NX 256 * 64
  2. #define NY 8
  3. #define N NY
  4.  
  5. #define IT 3

[edit] bs.h

  1. #include <stdlib.h> 
  2. #include <stdio.h>
  3. #include <sam.h>
  4.  
  5. #define utype int
  6. typedef int (*CMPFUN)(utype, utype);
  7.  
  8. void bubbleSort(utype *Array, CMPFUN fun, utype size, SAM_pdif_t dif);

[edit] bs.c

  1. #include "bs.h"
  2.  
  3. void bubbleSort(utype *Array, CMPFUN fun, int size, SAM_pdif_t dif)
  4. {
  5.   unsigned int ind1;
  6.   unsigned int ind2;
  7.   utype temp1;
  8.   utype temp2;
  9.   int flipped;
  10.  
  11.   if (size <= 1)
  12.     return;
  13.  
  14.   ind1 = 1;
  15.   do
  16.     {
  17.       flipped = 0;
  18.       for (ind2 = size - 1; ind2 >= ind1; --ind2)
  19. 	{
  20. 	  temp1 = __SAM_ADDR__(Array[ind2], dif);
  21. 	  temp2 = __SAM_ADDR__(Array[ind2 - 1], dif);
  22. 	  if ((*fun)(temp2, temp1) > 0)
  23. 	    {
  24. 	      __SAM_ADDR__(Array[ind2 - 1], dif) = temp1;
  25. 	      __SAM_ADDR__(Array[ind2], dif) = temp2;
  26. 	      flipped = 1;
  27. 	    }
  28. 	}
  29.     } while ((++ind1 < size) && flipped);
  30. }

[edit] Explanation

[edit] Compile Command

gcc example6.c bs.c -lsam -lpthread -o example6

[edit] Download