SAM Example 4

From SoOS

Jump to: navigation, search

Contents

[edit] Description

This example shows how to execute a worker thread that writes to memory speculatively.

[edit] Code

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sam.h>
  4.  
  5. #define N 1
  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 th[N]; /* For storing the worker threads ID's  */
  73.   int *result; /* Gets the result of the worker thread */
  74.   int *myArray; /* Pointer to the array of the data */
  75.   struct datast *data_arg; /* Pointer to the worker threads arguments */
  76.   int i;
  77.  
  78.  
  79.   myArray = (int *) malloc(ARRAY_SIZE *sizeof(int));
  80.   data_arg = (struct datast *) malloc(sizeof(struct datast));
  81.  
  82.  
  83.   /* Set some data into the Array */
  84.   for(i=0; i<ARRAY_SIZE; i++)
  85.     {
  86.       myArray[i] = i + 1000;
  87.     }
  88.  
  89.  
  90.   /* Initialize the SAM context */
  91.   SAM_Init(&sam_context);
  92.  
  93.   /* Setup the arguments we are going to send to the worker threads */
  94.   data_arg->A = myArray;
  95.  
  96.  
  97.   /* Register a region and protect it */
  98.   SAM_Memory_region_register(sam_context, myArray, ARRAY_SIZE * sizeof(int));
  99.   SAM_Memory_region_protect(sam_context, myArray);
  100.  
  101.  
  102.   for(i=0;i<N;i++)
  103.     {
  104.       /* Create the worker threads running worker_routine  */
  105.       th[i] = SAM_Execution_create(sam_context, *worker_routine, (void *)data_arg);
  106.     }
  107.  
  108.   /* ---------------------------------------- */
  109.   /* Prepare the region to write, this flashes back all the worker threads */
  110.   /* that already accesed to this region of memory */
  111.   SAM_Memory_write_prepare(sam_context, myArray);
  112.   for(i=0; i<ARRAY_SIZE; i++)
  113.     {
  114.       /* Create a delay to allow some context switches */
  115.       usleep(20*1000);
  116.       /* Set a new value in the array elements*/
  117.       myArray[i] = i;
  118.     }
  119.   /* Declare the region as written */
  120.   SAM_Memory_write(sam_context, myArray);
  121.   /* ---------------------------------------- */
  122.  
  123.  
  124.   for(i=0;i<N;i++)
  125.     {
  126.       /* Join the worker threads and get the result */
  127.       result = (int *)SAM_Execution_join(sam_context, th[i]);
  128.  
  129.       /* Print the result */
  130.       printf("RES %d: %d\n", i, *result);
  131.  
  132.       /* Do not forget to free the memory reserved to store the result */
  133.       free(result);
  134.     }
  135.  
  136.   /* Release and unregister the memory region*/
  137.   SAM_Memory_region_release(sam_context, myArray);
  138.   SAM_Memory_region_unregister(sam_context, myArray);
  139.  
  140.  
  141.   /* Destroy the SAM context */
  142.   SAM_Destroy(&sam_context);
  143.  
  144.   /* Show the array after memory speculative writing */
  145.   for(i=0; i<ARRAY_SIZE; i++)
  146.     {
  147.       printf("%d - %d\n", i, myArray[i]);
  148.     }
  149.  
  150.   /* Free the memory */
  151.   free(myArray);
  152.   free(data_arg);
  153.  
  154.   return 0;
  155. }

[edit] Explanation

This example shows how to execute a worker thread that writes to memory speculatively and flashes back when dependencies are detected.

To write speculatively first we have to declare a SAM_pdif_t variable (line 21) that stores the result of the call to the function SAM_Memory_write_prepare(), in the line 42, that will create a copy of the memory region into which the reads and writes are carried out using the macro __SAM_ADDR__(), which translates the memory addresses, as shown in the lines 49 and 51.

In the for loop in the line 145, the data array is printed on the screen, after the commits from the speculative writing is accepted as correct and merged into the memory of the main thread.

[edit] Compile Command

gcc example4.c -lsam -lpthread -o example4

[edit] Download