SAM Example 5

From SoOS

Jump to: navigation, search

Contents

[edit] Description

This example shows how to use multiple protected memory regions within the same SAM context.

[edit] Code

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sam.h>
  4.  
  5. #define N 2
  6. #define ARRAY_SIZE 64
  7.  
  8. struct datast
  9. {
  10.   int *A;
  11. };
  12.  
  13. void * worker_routine(void *args)
  14. {
  15.   SAM_t sam_context; /* Declare a SAM context variable */
  16.   void *myargs; /* Pointer to where the arguments are stored */
  17.   int *myArray; /* Pointer to the Array of the data */
  18.   struct datast *data_arg; /* Pointer to the arguments of the function */
  19.   int total; /* Store the variable of the calculation */
  20.   int *result; /* Pointer to the result (total) of the calculation */
  21.   SAM_pdif_t dif; /* The differential for the __SAM_ADDR__() macro*/
  22.   int i;
  23.  
  24.  
  25.   /* Start the execution of this worker thread */
  26.   /* Extract the SAM context and the arguments */
  27.   SAM_Execution_start(args, &sam_context, &myargs);
  28.  
  29.   /* Print the SAM worker ID of this worker thread  */
  30.   printf("SAM worker id: %d\n", (int)SAM_My_workid(sam_context));
  31.  
  32.   /* Extract the arguments of the function */
  33.   data_arg = (struct datast *) myargs;
  34.   myArray = data_arg->A;
  35.  
  36.   total = 0;
  37.  
  38.   /* Declare the region as read by the worker thread */
  39.   SAM_Memory_speculative_read(sam_context, SAM_My_workid(sam_context), myArray);
  40.  
  41.   /* Prepare the memory region for speculative write and obtain the differential parameter */
  42.   dif = SAM_Memory_speculative_write_prepare(sam_context, myArray);
  43.  
  44.  
  45.   /* Make some calculations... */
  46.   for(i=0; i<ARRAY_SIZE; i++)
  47.     {
  48.       /* Example on how to use the __SAM_ADDR__() for reading */
  49.       total += __SAM_ADDR__(myArray[i], dif);
  50.       /* Example on how to use the __SAM_ADDR__() for writing */
  51.       __SAM_ADDR__(myArray[i], dif) = __SAM_ADDR__(myArray[i], dif) *2;
  52.     }
  53.  
  54.   total = total * (int)SAM_My_workid(sam_context);
  55.  
  56.   /* Print the total, but this value might not be valid */
  57.   printf("Calculated %d: %d\n", (int)SAM_My_workid(sam_context), total);
  58.  
  59.   /* Finish the execution of this worker trhead */
  60.   SAM_Execution_finish(sam_context);
  61.  
  62.   /* Reserve memory for the result and return it */
  63.   result = (int *) malloc(sizeof(int));
  64.   *result = total;
  65.  
  66.   return result;
  67. }
  68.  
  69. int main(void)
  70. {
  71.   SAM_t sam_context; /* Declare a SAM context variable */
  72.   SAM_Workerid_t th1[N]; /* For storing the worker threads ID's of memory region 1*/
  73.   SAM_Workerid_t th2[N]; /* For storing the worker threads ID's of memory region 2*/
  74.   int *result; /* Gets the result of the worker thread */
  75.   int *myArray1; /* Pointer to the array 1 of the data */
  76.   int *myArray2; /* Pointer to the array 2 of the data */
  77.   struct datast *data_arg1; /* Pointer to the worker threads arguments */
  78.   struct datast *data_arg2; /* Pointer to the worker threads arguments */
  79.   int i;
  80.  
  81.  
  82.   myArray1 = (int *) malloc(ARRAY_SIZE *sizeof(int));
  83.   myArray2 = (int *) malloc(ARRAY_SIZE *sizeof(int));
  84.   data_arg1 = (struct datast *) malloc(sizeof(struct datast));
  85.   data_arg2 = (struct datast *) malloc(sizeof(struct datast));
  86.  
  87.  
  88.   /* Set some data into the Array */
  89.   for(i=0; i<ARRAY_SIZE; i++)
  90.     {
  91.       myArray1[i] = i + 1000;
  92.       myArray2[i] = i + 2000;
  93.     }
  94.  
  95.  
  96.   /* Initialize the SAM context */
  97.   SAM_Init(&sam_context);
  98.  
  99.   /* Setup the arguments we are going to send to the worker threads */
  100.   data_arg1->A = myArray1;
  101.   data_arg2->A = myArray2;
  102.  
  103.  
  104.   /* Register two regions and protect them */
  105.   SAM_Memory_region_register(sam_context, myArray1, ARRAY_SIZE * sizeof(int));
  106.   SAM_Memory_region_protect(sam_context, myArray1);
  107.   SAM_Memory_region_register(sam_context, myArray2, ARRAY_SIZE * sizeof(int));
  108.   SAM_Memory_region_protect(sam_context, myArray2);
  109.  
  110.   for(i=0;i<N;i++)
  111.     {
  112.       /* Create the worker threads running worker_routine  */
  113.       th1[i] = SAM_Execution_create(sam_context, *worker_routine, (void *)data_arg1);
  114.       th2[i] = SAM_Execution_create(sam_context, *worker_routine, (void *)data_arg2);
  115.     }
  116.  
  117.   /* ---------------------------------------- */
  118.   /* Prepare the region to write, this flashes back all the worker threads */
  119.   /* that already accesed to this region of memory */
  120.   SAM_Memory_write_prepare(sam_context, myArray1);
  121.   for(i=0; i<ARRAY_SIZE; i++)
  122.     {
  123.       /* Create a delay to allow some context switches */
  124.       usleep(20*1000);
  125.       /* Set a new value in the array elements*/
  126.       myArray1[i] = i;
  127.     }
  128.   /* Declare the region as written */
  129.   SAM_Memory_write(sam_context, myArray1);
  130.  
  131.  
  132.   /* Prepare the region to write, this flashes back all the worker threads */
  133.   /* that already accesed to this region of memory */
  134.   SAM_Memory_write_prepare(sam_context, myArray2);
  135.   for(i=0; i<ARRAY_SIZE; i++)
  136.     {
  137.       /* Create a delay to allow some context switches */
  138.       usleep(20*1000);
  139.       /* Set a new value in the array elements*/
  140.       myArray2[i] = i;
  141.     }
  142.   /* Declare the region as written */
  143.   SAM_Memory_write(sam_context, myArray2);
  144.   /* ---------------------------------------- */
  145.  
  146.  
  147.   for(i=0;i<N;i++)
  148.     {
  149.       /* Join the worker threads and get the result */
  150.       result = (int *)SAM_Execution_join(sam_context, th1[i]);
  151.  
  152.       /* Print the result */
  153.       printf("RES %d: %d\n", i, *result);
  154.  
  155.       /* Do not forget to free the memory reserved to store the result */
  156.       free(result);
  157.     }
  158.  
  159.   for(i=0;i<N;i++)
  160.     {
  161.       /* Join the worker threads and get the result */
  162.       result = (int *)SAM_Execution_join(sam_context, th2[i]);
  163.  
  164.       /* Print the result */
  165.       printf("RES %d: %d\n", i, *result);
  166.  
  167.       /* Do not forget to free the memory reserved to store the result */
  168.       free(result);
  169.     }
  170.  
  171.   /* Release and unregister the memory regions*/
  172.   SAM_Memory_region_release(sam_context, myArray1);
  173.   SAM_Memory_region_unregister(sam_context, myArray1);
  174.   SAM_Memory_region_release(sam_context, myArray2);
  175.   SAM_Memory_region_unregister(sam_context, myArray2);
  176.  
  177.   /* Destroy the SAM context */
  178.   SAM_Destroy(&sam_context);
  179.  
  180.   /* Show the array after memory speculative writing */
  181.   for(i=0; i<ARRAY_SIZE; i++)
  182.     {
  183.       printf("1: %d - %d\n", i, myArray1[i]);
  184.       printf("2: %d - %d\n", i, myArray2[i]);
  185.     }
  186.  
  187.   /* Free the memory */
  188.   free(myArray1);
  189.   free(myArray2);
  190.   free(data_arg1);
  191.   free(data_arg2);
  192.  
  193.   return 0;
  194. }

[edit] Explanation

[edit] Compile Command

gcc example5.c -lsam -lpthread -o example5

[edit] Download