void sched_init() { debugState = debugDisabled; en_idle = 1; currentType = 0; currentIndex = 0; int i, j; for (i = 0; i < 3; i++) { for (j = 0; j < task_type_max(i); j++) { tareasInfo[i][j].alive = 0; tareasInfo[i][j].owner = 0; tareasInfo[i][j].gdtIndex = 0; tareasInfo[i][j].x = 0; tareasInfo[i][j].y = 0; tareasInfo[i][j].mapped_x = 0; tareasInfo[i][j].mapped_y = 0; } tareasIndices[i] = 0; } srand(0); for (i = 0; i < 15; i++) { unsigned short y = rand_in_range(0, 43); unsigned short x = rand_in_range(0, 79); sched_lanzar_tareas(0, x, y); } }
double metropolis_update(double* path, double g, int n_sweeps, int nt, double D) { int sweep, tstep; double shift, dS, accept_prob; /* Return path after performing metropolis hastings updating for n_sweeps sweeps */ for(sweep = 0; sweep < n_sweeps; sweep++) { for(tstep = 0; tstep < nt; tstep++) { /* Get a Random Shift */ shift = rand_in_range(-1.0*D, D); /* Compute change in action */ dS = delta_S(path, g, shift, tstep); /* Determine acceptance probability */ accept_prob = fmin(1.0, exp(-1.0*dS)); if(rand_in_range(0.0, 1.0) <= accept_prob) { /* accept the shift */ path[tstep] += shift; } } } return 0; }
/** * Returns a number between MIN_COMP_TIME and a fraction of period time */ unsigned int get_comp_time(int period) { unsigned int max_comp_time = (unsigned int)(period * MAX_COMP_TIME_TO_PERIOD_RATIO); if(max_comp_time < MIN_COMP_TIME) { max_comp_time = MIN_COMP_TIME; } return rand_in_range(MIN_COMP_TIME, max_comp_time); }
/** * This verifies that * 1) the load is evenly balanced across servers. * 2) the act of adding a server to a pool will never result in a server * handling keyspace that it previously handled but no longer does. * If this occurs, then stale data may be returned. */ TEST(ch3, verify_correctness) { uint32_t i, j; uint32_t maximum_pool_size = furc_maximum_pool_size(); char key[MAX_KEY_LENGTH + 1]; std::vector<uint64_t> pools[NUM_POOLS]; uint32_t sizes[NUM_POOLS]; size_t num_pools; auto weights = std::make_unique<std::array<double, 1U << 23U>>(); weights->fill(1.0); srand(time(nullptr)); for (num_pools = 0; /* see end of loop */; ++num_pools) { if (num_pools == 0) { sizes[num_pools] = 1; } else if (num_pools == NUM_POOLS - 1) { sizes[num_pools] = maximum_pool_size; } else if (num_pools % 2 == 1) { // grow pool size geometrically sizes[num_pools] = sizes[num_pools - 1] * drand_in_range(1.5, 2.5); } else { // grow pool size arithmetically sizes[num_pools] = sizes[num_pools - 1] + rand_in_range(1, 11); } /* Make sure we don't exceed the maximum pool size. */ if (sizes[num_pools] > maximum_pool_size) { sizes[num_pools] = maximum_pool_size; } pools[num_pools] = std::vector<uint64_t>(sizes[num_pools]); if (sizes[num_pools] == maximum_pool_size) break; } for (i = 0; i < NUM_SAMPLES; ++i) { size_t previous_num = -1; int len; make_random_key(key, MAX_KEY_LENGTH); len = strlen(key); // hash the same key in each pool, in increasing pool size order for (j = 0; j < num_pools; ++j) { size_t num = furc_hash(key, len, sizes[j]); EXPECT_LT(num, sizes[j]); // Verify that the weighted furc yields identical result with weights at 1 assert(sizes[j] <= weights->size()); folly::Range<const double*> weightRange( weights->cbegin(), weights->cbegin() + sizes[j]); size_t weighted = facebook::mcrouter::weightedFurcHash( folly::StringPiece(key, len), weightRange); EXPECT_EQ(num, weighted); ++pools[j][num]; // make sure that this key either hashes the same server, // or hashes to a new server if (previous_num != num && j > 0) { EXPECT_GE(num, sizes[j - 1]); } previous_num = num; } } for (i = 0; i < num_pools; ++i) { /* Verify that load is evenly distributed. This isn't easy to do generally without significantly increasing the runtime by choosing a huge NUM_SAMPLES, so just check pools up to 1000 in size. */ uint32_t pool_size = sizes[i]; if (pool_size > 1000) break; double expected_mean = ((double)NUM_SAMPLES) / pool_size; double max_diff = 0; double sum = 0; for (j = 0; j < pool_size; j++) { double diff = std::abs(pools[i][j] - expected_mean); if (diff > max_diff) max_diff = diff; sum += pools[i][j]; } double mean = sum / pool_size; // expect the sample mean to be within 5% of expected mean EXPECT_NEAR(mean, expected_mean, expected_mean * 0.05); // expect the maximum deviation from mean to be within 15% EXPECT_NEAR(max_diff, 0, mean * 0.15); sum = 0; for (j = 0; j < pool_size; j++) { double diff = pools[i][j] - mean; sum += diff * diff; } double stddev = sqrt(sum / pool_size); // expect the standard deviation to be < 5% EXPECT_NEAR(stddev, 0, mean * 0.05); } }
/** * Returns a number between MIN_PERIOD and MAX_PERIOD */ unsigned int get_period() { return rand_in_range(MIN_PERIOD, MAX_PERIOD); }
/** * Returns a random number between MIN_ITERATIONS and MAX_ITERATIONS */ unsigned int get_iterations() { return rand_in_range(MIN_ITERATIONS, MAX_ITERATIONS); }