int main (int argc, char *argv[]) { struct l2atomic l2atomic; memset((void*)&l2atomic, 0, sizeof(l2atomic)); uint32_t tcoord = Kernel_MyTcoord(); int rc, lineno; rc = l2atomic_init(&l2atomic); lineno = __LINE__; if (rc) goto err; volatile uint64_t * buffer = NULL; rc = l2atomic_alloc(&l2atomic, "simple", sizeof(uint64_t)*3, (void**)&buffer, test_init_fn, 0); lineno = __LINE__; if (rc) goto err; volatile uint64_t * entered = buffer+1; volatile uint64_t * exited = buffer+2; L2_AtomicLoadIncrement(entered); uint32_t i; if (tcoord % 2 == 0) { for (i=0; i<ITERATIONS; ++i) L2_AtomicLoadIncrement(buffer); } else { for (i=0; i<ITERATIONS; ++i) L2_AtomicLoadDecrement(buffer); } L2_AtomicLoadIncrement(exited); while (L2_AtomicLoad(exited) != *entered); uint64_t np = *entered; uint64_t expected = 0; if (np % 2 == 1) expected = ITERATIONS; if (tcoord == 0) fprintf (stdout, "l2atomic value: %lu (expected %lu)\n", *buffer, expected); if (*buffer == expected) { if (tcoord == 0) fprintf (stdout, "TEST SUCCESSFUL\n"); } else { if (tcoord == 0) fprintf (stdout, "TEST FAILED\n"); return 1; } return 0; err: fprintf (stderr, "Error at line %d\n", lineno); return 1; }
/*! * \brief Allocates a speculative domain. * \note Each additional domain potentially decreases the number of speculative IDs assigned to each domain. * \note Domains must have all speculative IDs set to the available state */ int Speculation_AllocateDomain(unsigned int* domain) { #if 0 const unsigned char domainmap[17] = { 1, 1, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16}; if(NodeState.NumSpecDomains >= 16) { return ENOMEM; } if(!SPEC_AllAvailOrInvalid()) { // if any ID is speculative or committed, we can not switch // \todo this needs to be made safe. // While switching, we can not allow threads to alloce concurrently (race) // TM domains need to be made aware of changes to adapt their allocation mask // In short, all speculation RTS need to be shut down temporarily while changing number of domains return ENOMEM; } NodeState.NumSpecDomains++; SPEC_SetNumberOfDomains( domainmap[NodeState.NumSpecDomains] ); SPEC_SetDomainMode_priv(NodeState.NumSpecDomains-1, L2C_DOMAINATTR_MODE_STM); ppc_msync(); /* \todo Initialize commit, alloc, reclaim pointers??? */ *domain = NodeState.NumSpecDomains-1; #endif uint32_t domainAllocated = L2_AtomicLoadIncrement(&SpecDomainsAllocated); if(domainAllocated >= SPEC_GetNumberOfDomains()) { return ENOMEM; } // bqcbugs 1620. l2_set_prefetch_enables(0); l2_unlock_all_with_address((void *) 0x200000); l2_set_overlock_threshold(0xA); // set L2 overlock and spec thresholds l2_set_spec_threshold(0xA); // -- Kernel_WriteFlightLog(FLIGHTLOG_high, FL_SPCALCDOM, domainAllocated,0,0,0); *domain = domainAllocated; return 0; }
int main(int argc, char * argv[]) { const int n = 1024; int count = (argc>1) ? atoi(argv[1]) : 1000000; /* this "activates" the L2 atomic data structures */ uint64_t * l2_counters = NULL; int rc = posix_memalign((void**)&l2_counters, 2*1024*1024, n * sizeof(uint64_t) ); assert(rc==0 && l2_counters != NULL); uint64_t rc64 = Kernel_L2AtomicsAllocate(l2_counters, n * sizeof(uint64_t) ); assert(rc64==0); for (int i=0; i<n; i++) { L2_AtomicStore(&(l2_counters[i]), 0); } #pragma omp parallel shared(l2_counters) { int me = omp_get_thread_num(); int jmax = n/omp_get_num_threads(); for (int j=0; j<jmax; j++) { #pragma omp barrier uint64_t t0 = GetTimeBase(); for (int i=0; i<count; i++) { L2_AtomicLoadIncrement(&(l2_counters[j*me])); } #pragma omp barrier uint64_t t1 = GetTimeBase(); printf("threads = %d, stride = %d, ticks = %llu \n", omp_get_num_threads(), j, t1-t0); fflush(stdout); } } for (int i=0; i<n; i++) { uint64_t rval = L2_AtomicLoad(&(l2_counters[i])); printf("l2_counter[%d]=%llu\n", i, rval); } return 0; }
void * fight(void * input) { int tid = get_thread_id(); if (debug) printf("%d: before L2_Barrier 1 \n", tid); L2_Barrier(&barrier, num_threads); if (debug) { printf("%d: after L2_Barrier 1 \n", tid); fflush(stdout); } int count = 1000000; uint64_t rval; uint64_t t0 = GetTimeBase(); for (int i=0; i<count; i++) rval = L2_AtomicLoadIncrement(&(counter.atom)); uint64_t t1 = GetTimeBase(); if (debug) printf("%d: before L2_Barrier 2 \n", tid); L2_Barrier(&barrier, num_threads); if (debug) { printf("%d: after L2_Barrier 2 \n", tid); fflush(stdout); } uint64_t dt = t1-t0; printf("%2d: %d calls to %s took %llu cycles per call \n", tid, count, "L2_AtomicLoadIncrement", dt/count); fflush(stdout); pthread_exit(NULL); return NULL; }