void do_libtm_work(void) { int tstep, i; for ( tstep=0; tstep< NUMBER_TIMESTEPS; tstep++) { //printf("\n1");PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); PARALLEL_EXECUTE( NTHREADS, UpdateCoordinates, NULL ); //printf("\n2");PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); vir = 0.0; epot = 0.0; ekin = 0.0; vel = 0.0; count = 0.0; if ( tstep % neighUpdate == 0) { ninter = 0; PARALLEL_EXECUTE( NTHREADS, BuildNeigh, NULL ); //printf("\n3");PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); # ifdef PRINT_COORDINATES PrintCoordinates(numMoles); # endif # ifdef PRINT_INTERACTION_LIST PrintInteractionList(INPARAMS ninter); # endif # ifdef MEASURE PrintConnectivity(); # endif } /* for (i = 0; i < numMoles; ++i) { f[IND(0, i)] = 0; f[IND(0, i)] = 0; f[IND(0, i)] = 0; } */ PARALLEL_EXECUTE( NTHREADS, ComputeForces, NULL ); //printf("\n4");PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); PARALLEL_EXECUTE( NTHREADS, UpdateVelocities, NULL ); //printf("\n5");PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); PARALLEL_EXECUTE( NTHREADS, ComputeKE, NULL ); //printf("\n6");PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); PARALLEL_EXECUTE( NTHREADS, ComputeAvgVel, NULL ); //printf("\n7"); PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); } TM_END(); return; }
//main work function for each thread void * do_thread_work (void * _id) { int id = (int) _id; int tstep, i; cpu_set_t mask; CPU_ZERO( &mask ); #ifdef WITH_SMT CPU_SET( id*2, &mask ); #else CPU_SET( id, &mask ); #endif sched_setaffinity(0, sizeof(mask), &mask); for ( tstep=0; tstep< NUMBER_TIMESTEPS; tstep++) { barrier_wait (&barrier); //need to reset these global vars in the beginning of every timestep //global vars, need to be protected if (id == 0) { vir = 0.0; epot = 0.0; ekin = 0.0; vel = 0.0; count = 0.0; } //because we have this barrier here, we don't need one at the end of //each timestep; this barrier effectively acts as if it was at the end; //we need it here because we need to perform the initializations above //at the _beginning_ of each timestep. //No, you need a barrier at the end, as well, because if you only have one //here but not at the end, you may reset some of the above global vars //while a slower thread is still computing stuff in the previous timestep... //I'm not sure, but we may be able to replace this barrier with just //asm volatile("mfence" ::: "memory"); barrier_wait (&barrier); //UpdateCoordinates (NULL, id); //PARALLEL_EXECUTE( NTHREADS, UpdateCoordinates, NULL ); //barrier_wait (&barrier); if ( tstep % neighUpdate == 0) { //this barrier needed because of the single-threaded code below barrier_wait (&barrier); if (id == 0) { #ifdef PRINT_COORDINATES PrintCoordinates(numMoles); #endif //global var, needs to be protected ninter = 0; } //this barrier needed because of the single-threaded code above barrier_wait (&barrier); BuildNeigh (NULL, id); //PARALLEL_EXECUTE( NTHREADS, BuildNeigh, NULL ); //this barrier needed because of the single-threaded code below barrier_wait (&barrier); if (id == 0) { #ifdef PRINT_INTERACTION_LIST PrintInteractionList(INPARAMS ninter); #endif #ifdef MEASURE PrintConnectivity(); #endif } //we need this here because otherwise fast threads might start //changing the data that thread 0 is reading above while running //PrintInteractionList() and PrintConnectivity(). barrier_wait (&barrier); } ComputeForces (NULL, id); //PARALLEL_EXECUTE( NTHREADS, ComputeForces, NULL ); //this barrier disappears with relaxed predicated commits barrier_wait (&barrier); //UpdateVelocities (NULL, id); //PARALLEL_EXECUTE( NTHREADS, UpdateVelocities, NULL ); //this barrier disappears with relaxed predicated commits //barrier_wait (&barrier); //ComputeKEVel (NULL, id); //PARALLEL_EXECUTE( NTHREADS, ComputeKEVel, NULL ); //Mike: consolidated all update functions into 1 Update(NULL, id); //need a barrier at the end of each timestep barrier_wait (&barrier); if (id == 0) { PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); } barrier_wait (&barrier); } return NULL; }