Beispiel #1
0
double get_latency_bc(int n, size_t size) {
    int idx, i;
    char *data;
    bc_plist_t *other = NULL;
    bc_chan_t *src = NULL, *sink = NULL;
    bc_dtype_t *ntype;
    double start, *times;

    data = (char *) malloc(sizeof (char)*size);
    ntype = bc_dtype_create(sizeof (char)*size);

    /* We collect the value of the second get()
     * Rank 0 is sender, Rank 1 is producer. */
    if (bc_rank == 0) {
        other = bc_plist_create(1, 1);
        sink = bc_sink_create(other, ntype, 10, BC_ROLE_PIPE);

        for (i = 0; i < n; i++) {
            memset(data, bc_rank + 'a', size);
            /* Put data. */
            bc_put(sink, data, 1);
            bc_put(sink, data, 1);
        }

        bc_chan_destroy(sink);
        bc_plist_destroy(other);
        bc_dtype_destroy(ntype);

        return 0;
    } else {
        times = (double *) malloc(sizeof (double)*n);
        other = bc_plist_create(1, 0);
        src = bc_src_create(other, ntype, BC_ROLE_PIPE);

        for (i = 0; i < n; i++) {
            /* Get data. */
            bc_get(src, data, 1); /* Ignore this. */
            start = bc_gettime_usec();
            bc_get(src, data, 1); /* Take this value. */
            times[i] = bc_gettime_usec() - start;
        }

        bc_chan_destroy(src);
        bc_plist_destroy(other);
        bc_dtype_destroy(ntype);

        /* Find the median. */
        qsort(times, n, sizeof (double), comp);
        idx = n / 2;
        if (n % 2) {
            start = times[idx];
        } else {
            start = (times[idx - 1] + times[idx + 1]) / 2;
        }
        free(data);
        free(times);
        return start;
    }
}
Beispiel #2
0
double reduce_bc(int n, size_t size) {
    int idx, i;
    char *data, value;
    bc_plist_t *other = NULL;
    bc_chan_t *src = NULL, *sink = NULL;
    bc_dtype_t *ntype;
    double start, *times;

    data = (char *) malloc(sizeof (char)*size);
    ntype = bc_dtype_create(sizeof (char)*size);
    times = (double *) malloc(sizeof (double)*n);

    /* Root of the reduction. */
    if (bc_rank == 0) {
        sink = bc_sink_create(bc_plist_xall, ntype, 2, BC_ROLE_REPLICATE);
        src = bc_src_create(bc_plist_xall, ntype, BC_ROLE_REDUCE_SUM);

        for (i = 0; i < n; i++) {
            /* Put data. */
            start = bc_gettime_usec();
            bc_get(src, &value, 1);
            times[i] = bc_gettime_usec() - start;
            bc_put(sink, &value, 1); /* Wait for acknowledgement. */
        }
    } else {
        other = bc_plist_create(1, 0);
        src = bc_src_create(other, ntype, BC_ROLE_PIPE);
        sink = bc_sink_create(other, ntype, 1, BC_ROLE_PIPE);

        for (i = 0; i < n; i++) {
            memset(data, bc_rank + 'a', size * bc_size);
            /* Get data. */
            start = bc_gettime_usec();
            bc_get(src, data, 1); /* Take this value. */
            times[i] = bc_gettime_usec() - start;
            bc_put(sink, data, 1); /* Send acknowledgement. */
        }

        bc_plist_destroy(other);
    }

    bc_chan_destroy(src);
    bc_chan_destroy(sink);
    bc_dtype_destroy(ntype);

    /* Find the median. */
    qsort(times, n, sizeof (double), comp);
    idx = n / 2;
    if (n % 2) {
        start = times[idx];
    } else {
        start = (times[idx - 1] + times[idx + 1]) / 2;
    }
    free(data);
    free(times);
    return start;
}
Beispiel #3
0
static int mva (int print_intermediate)
{
	int i = bc_rank, j;
	float one_less;		/* Queue length with one less class r request. */
	float sum_qlens;	/* Sum of the queue lengths except for the current class. */
	float sum_resis;	/* Sum of the residence times for the current class. */
	bc_chan_t *src_data, *sink_data;
	bc_chan_t *src_err, *sink_err;

	/* Estimate queue lengths. */ 
	for (j = 0; j < nqueue; j++)
		if (val(serv_demand,i,j) > 0)
			val(qlen_est,i,j) = (float)load_vect[i]/visit_vect[i];

	/* Create communication structure for data transfer. */
	sink_data = bc_sink_create (bc_plist_xall, bc_float, 10, BC_ROLE_REPLICATE);
	src_data = bc_src_create (bc_plist_xall, bc_float, BC_ROLE_REDUCE_SUM);

	/* Create communication structure for relative error. */
	sink_err = bc_sink_create (bc_plist_xall, bc_float, 10, BC_ROLE_REPLICATE);
	src_err = bc_src_create (bc_plist_xall, bc_float, BC_ROLE_REDUCE_MAX);

	
	/* During parallelisation, the following do loop is executed at
	 * each process, which represents a class. The interprocess 
	 * communications happens during the calculation of 'sum_qlens'
	 * and determination of the relative error. */
	do {
		for (j = 0; j < nqueue; j++)
			val(qlen,i,j) = val(qlen_est,i,j);	

		for (j = 0; j < nqueue; j++) {
			/* Queue length with one less class i request. */
			bc_put (sink_data, ptr(qlen,i,j), 1);
			bc_get (src_data, &sum_qlens, 1);
			one_less = (load_vect[i] - 1)/load_vect[i]*val(qlen,i,j) + sum_qlens;
			
			/* Class i residence time at queue j. */
			if (qtype[j] == DELAY)
				val(res_time,i,j) = val(serv_demand,i,j);
			else
				val(res_time,i,j) = val(serv_demand,i,j)*(1.0 + one_less);
		}
		/* Throughput for class i. */
		sum_resis = 0.0;
		for (j = 0; j < nqueue; j++)
			sum_resis += val(res_time,i,j);
		throughput[i] = load_vect[i]/sum_resis;
		
		/* Compute new estimates for the queue lengths. */
		for (j = 0; j < nqueue; j++)
			val(qlen_est,i,j) = throughput[i]*val(res_time,i,j);			
	} while (!isdone(src_err, sink_err));

	/* Destroy communication structure. */
	bc_chan_destroy (src_data); bc_chan_destroy (sink_data);
	bc_chan_destroy (src_err); bc_chan_destroy (sink_err);
	return 0;
}
Beispiel #4
0
static int isdone(bc_chan_t *src, bc_chan_t *sink)
{
	int i = bc_rank, j;
	float rerror = 0.0; /* Relative error. */
	float merror = 0.0; /* Maximum relative error. */
	float r_error;		/* Maximum error from remote. */

	for (j = 0; j < nqueue; j++) {
		rerror = fabs((val(qlen_est,i,j) - val(qlen,i,j))/val(qlen_est,i,j));
		if (rerror > merror) merror = rerror;
	}
	bc_put (sink, &merror, 1);
	bc_get (src, &r_error, 1);
	if (merror > r_error) merror = r_error;
	if (merror < epsilon) return 1;
	else return 0;
}
Beispiel #5
0
char *hs_get(HStore *store, char *key, int *vlen, uint32_t *flag)
{
    if (!key || !store) return NULL;

    if (key[0] == '@'){
        char *r = hs_list(store, key+1);
        if (r) *vlen = strlen(r);
        *flag = 0;
        return r;
    }
    
    bool info = false;
    if (key[0] == '?'){
        info = true;
        key ++;
    }
    int index = get_index(store, key);
    DataRecord *r = bc_get(store->bitcasks[index], key);
    if (r == NULL){
        return NULL;
    }
    
    char *res = NULL;
    if (info){
        res = malloc(256);
        if (!res) {
            free_record(r);
            return NULL;
        }
        uint16_t hash = 0;
        if (r->version > 0){
            hash = gen_hash(r->value, r->vsz);
        }
        *vlen = snprintf(res, 255, "%d %u %u %u %u", r->version, 
            hash, r->flag, r->vsz, r->tstamp);
        *flag = 0;
    }else if (r->version > 0){
        res = record_value(r);
        r->value = NULL;
        *vlen = r->vsz;
        *flag = r->flag;
    }
    free_record(r);
    return res;
}
Beispiel #6
0
void stage_4(void *out)
{
	bc_plist_t *ipl;
	bc_chan_t *ibc;
	int i = 0;

	ipl = bc_plist_create(1, 2);
	ibc = bc_src_create(ipl, bc_int, BC_ROLE_PIPE);

	*((int *) out + 0) = 0;
	for (i= 0; i < 20; i++) {
		bc_get(ibc, (int *)out + 1, 1);
		*((int *) out + 0) += *((int *) out + 1);
	}

	bc_chan_destroy(ibc);
	bc_plist_destroy(ipl);
}
Beispiel #7
0
bool bc_set(Bitcask *bc, const char* key, char* value, int vlen, int flag, int version)
{
    if (version < 0 && vlen > 0 || vlen > MAX_RECORD_SIZE)
    {
        fprintf(stderr, "invalid set cmd \n");
        return false;
    }

    bool suc = false;
    pthread_mutex_lock(&bc->write_lock);

    int oldv = 0, ver = version;
    Item *it = ht_get(bc->tree, key);
    if (it != NULL)
    {
        oldv = it->ver;
    }

    if (version == 0 && oldv > 0)  // replace
    {
        ver = oldv + 1;
    }
    else if (version == 0 && oldv <= 0)    // add
    {
        ver = -oldv + 1;
    }
    else if (version < 0 && oldv <= 0)     // delete, not exist
    {
        goto SET_FAIL;
    }
    else if (version == -1)     // delete
    {
        ver = - abs(oldv) - 1;
    }
    else if (abs(version) <= abs(oldv))     // sync
    {
        goto SET_FAIL;
    }
    else     // sync
    {
        ver = version;
    }

    uint16_t hash = gen_hash(value, vlen);
    if (ver < 0) hash = 0;

    if (NULL != it && hash == it->hash)
    {
        DataRecord *r = bc_get(bc, key);
        if (r != NULL && r->flag == flag && vlen  == r->vsz
                && memcmp(value, r->value, vlen) == 0)
        {
            if (version != 0)
            {
                // update version
                if (it->pos & 0xff == bc->curr)
                {
                    ht_add(bc->curr_tree, key, it->pos, it->hash, ver);
                }
                ht_add(bc->tree, key, it->pos, it->hash, ver);
            }
            suc = true;
            free_record(r);
            goto SET_FAIL;
        }
        if (r != NULL) free_record(r);
    }

    int klen = strlen(key);
    DataRecord *r = (DataRecord*)malloc(sizeof(DataRecord) + klen);
    r->ksz = klen;
    memcpy(r->key, key, klen);
    r->vsz = vlen;
    r->value = value;
    r->free_value = false;
    r->flag = flag;
    r->version = ver;
    r->tstamp = time(NULL);

    int rlen;
    char *rbuf = encode_record(r, &rlen);
    if (rbuf == NULL || (rlen & 0xff) != 0)
    {
        fprintf(stderr, "encode_record() failed with %d\n", rlen);
        if (rbuf != NULL) free(rbuf);
        goto SET_FAIL;
    }

    pthread_mutex_lock(&bc->buffer_lock);
    // record maybe larger than buffer
    if (bc->wbuf_curr_pos + rlen > bc->wbuf_size)
    {
        pthread_mutex_unlock(&bc->buffer_lock);
        bc_flush(bc, 0, 0);
        pthread_mutex_lock(&bc->buffer_lock);

        while (rlen > bc->wbuf_size)
        {
            bc->wbuf_size *= 2;
            free(bc->write_buffer);
            bc->write_buffer = (char*)malloc(bc->wbuf_size);
        }
        if (bc->wbuf_start_pos + bc->wbuf_size > MAX_BUCKET_SIZE)
        {
            bc_rotate(bc);
        }
    }
    memcpy(bc->write_buffer + bc->wbuf_curr_pos, rbuf, rlen);
    int pos = (bc->wbuf_start_pos + bc->wbuf_curr_pos) | bc->curr;
    bc->wbuf_curr_pos += rlen;
    pthread_mutex_unlock(&bc->buffer_lock);

    ht_add(bc->curr_tree, key, pos, hash, ver);
    ht_add(bc->tree, key, pos, hash, ver);
    suc = true;
    free(rbuf);
    free_record(r);

SET_FAIL:
    pthread_mutex_unlock(&bc->write_lock);
    if (it != NULL) free(it);
    return suc;
}