Search in shivacherukuri.tech@blogger.com

Sunday, February 20, 2011

Binding a thread/process to a spu

 

Please go through the following sample call for binding a processor thread to a spu:

 

# cat nu_ht.c  sample_itc.c

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <errno.h>

#include <string.h>

#include <unistd.h>

#include <assert.h>

#define _PSTAT64

#include <sys/pstat.h>

 

 

#define MAXCPUS         (8)

 

typedef uint64_t pcarray[2][4][MAXCPUS][2]; pcarray pca;

pthread_spu_t check_spu = -1;

 

 

void* busy_thrd(void *); /* this thread busy loops in a processor */

void* pstat_thrd(void *); /* this thread continuously monitors pstat call on sibiling thread */

int setarray(int t);

 

 

int main(int argc, char* argv[])

{

  pthread_t bthrd, pthrd;

  pthread_spu_t spu1, spu2;

 

  printf ("where do you want to run busy thread: ");

  scanf ("%d", &spu1);

  printf ("where do you want to run pstat thread: ");

  scanf ("%d", &spu2);

  printf ("Where do you want to check: ");

  scanf ("%d", &check_spu);

 

  if (pthread_create(&bthrd, 0, busy_thrd,(void *) &spu1) != 0)   {

     printf("Printing busy thread create failed\n");

     exit(0);

     }

  else    {

     printf("Printing thread id = %d created.\n", bthrd);

     }

 

  if (pthread_create(&pthrd, 0, pstat_thrd,(void *) &spu2) != 0)   {

     printf("Printing pstat thread create failed\n");

     exit(0);

     }

  else    {

     printf("Printing thread id = %d created.\n", pthrd);

     }

 

//  Now unblock suspended threads.

//  pthread_continue(pthrd);

//  pthread_continue(bthrd);

 

 

//  Wait for both threads to finish

  pthread_join(pthrd, 0);

  pthread_join(bthrd, 0);

 

 

  printf("main ends after threads %d and %d\n", pthrd, bthrd);

 

  return 0;

}

 

void* busy_thrd(void *p)

{

   pthread_spu_t spu = *((pthread_spu_t *) p);

   pthread_spu_t ans_spu;

   printf ("We are in busy thread on spu: %d\n", *((int *) p));

   if (pthread_processor_bind_np (PTHREAD_BIND_FORCED_NP, &ans_spu,

                                  spu, PTHREAD_SELFTID_NP) != 0) {

       printf("Printing busy thread bind failed.\n");

       }

   else

       printf ("Busy thread> Bind to spu, %d .... SUCESS\n", ans_spu);

   while (1);

}

 

 

void* pstat_thrd(void *p)

{

   pthread_spu_t spu = *((pthread_spu_t *) p);

   pthread_spu_t ans_spu;

   int cpu, state, oldt, newt, cpus, r;

   unsigned int counter = 0;

 

   printf ("We are in pstat thread on spu: %d\n", *((int *) p));

   if (pthread_processor_bind_np (PTHREAD_BIND_FORCED_NP, &ans_spu,

                                  spu, PTHREAD_SELFTID_NP) != 0) {

       printf("Printing pstat thread bind failed.\n");

       }

   else

       printf ("pstat thread> Bind to spu, %d .... SUCESS\n", ans_spu);

 

   cpus = setarray(oldt = 0);

   newt = 1;

   while ( cpus > 0 ) {

        r = setarray(newt);

        if ( cpus > r )

          cpus = r;

        for ( state=0; state<4; ++state )

//           for ( cpu=0; cpu<cpus; ++cpu ) {

              if ( ( pca[newt][state][check_spu][1] < pca[oldt][state][check_spu][1] )  &&

                   ( pca[newt][state][check_spu][0] <= pca[oldt][state][check_spu][0] ) ) {

                  printf("pca[%d][%3d]=%llu.%llu <",state,check_spu,

                          pca[newt][state][check_spu][0],pca[newt][state][check_spu][1] );

                  printf("pca[%d][%3d]=%llu.%llu\n",state,check_spu,

                          pca[oldt][state][check_spu][0],pca[oldt][state][check_spu][1] );

              }

//        }

        newt = 1 - newt;

        oldt = 1 - oldt;

   }

}

 

int setarray(int t) {

 int cpu,r;

 struct pst_processor pgp[MAXCPUS];

 

 if ( ( r = pstat_getprocessor(&pgp[0],sizeof(pgp[0]),MAXCPUS,0) ) <= 0 ) {

   perror("pstat_getprocessor");

   exit(1);

 }

 for ( cpu=0; cpu<r; ++cpu) {

    pca[t][0][cpu][0] = pgp[cpu].psp_usercycles.psc_hi;

    pca[t][0][cpu][1] = pgp[cpu].psp_usercycles.psc_lo;

    pca[t][1][cpu][0] = pgp[cpu].psp_systemcycles.psc_hi;

    pca[t][1][cpu][1] = pgp[cpu].psp_systemcycles.psc_lo;

    pca[t][2][cpu][0] = pgp[cpu].psp_interruptcycles.psc_hi;

    pca[t][2][cpu][1] = pgp[cpu].psp_interruptcycles.psc_lo;

    pca[t][3][cpu][0] = pgp[cpu].psp_idlecycles.psc_hi;

    pca[t][3][cpu][1] = pgp[cpu].psp_idlecycles.psc_lo;

    }

 return r;

}

 

 

sample_itc.c

 

#include <ia64/sys/kern_inline.h>

#include <stdio.h>

#include <pthread.h>

#include <stdlib.h>

#include <assert.h>

 

main()   {

    unsigned long old, new;

    pthread_spu_t spu;

 

    if ( pthread_processor_bind_np(PTHREAD_BIND_FORCED_NP, &spu,

                                   PTHREAD_SPUNOCHANGE_NP,

                                   PTHREAD_SELFTID_NP) != 0)   {

         printf("ERROR!! Unable to get processor bind info.\n");

         perror("ERROR!! Compute(processor bind info error)");

         exit (-10);

         }

 

    printf("Compute thread: processor bind = %d\n", spu);

 

    while (1) {

        if (old >= (new = _MOV_FROM_AR(_AREG_ITC))) {

            printf ("old: %lx, new: %lx\n", old, new);

            assert (0);

            }

        old = new;

        }

    }

 

#

 

 

 

No comments:

Post a Comment