int CFileOp::reopen(bool create) { if(m_isopen) Close(); m_isopen = true; if(m_open(m_name, create)) return 1; return 0; }
double m_input(float *p,short n_args,double *pp) { p[1] = (n_args > 1) ? p[1] : 0.; p[2] = 0; n_args = 3; if (get_print_option()) fprintf(stderr,"Opening input file as unit %d\n",(int)p[1]); return m_open(p,n_args,pp); }
double m_output(float *p,short n_args,double *pp) { int i; p[1] = (n_args > 1) ? p[1] : 1.; p[2] = 2; n_args = 3; i = p[0]; if (get_print_option()) fprintf(stderr,"Opening output file as unit %d\n",(int)p[1]); return m_open(p,n_args,pp); }
int main(int argc, char *argv[]) { int opt; int hasEnded = 0; int i; for (i=0; i < MAX_SEM; i++) sem_array[i] = SEM_FAILED; while ( !hasEnded ) { printf("Escriba la opcion deseada\n1 - OPEN\t2 - WAIT\t3 - POST\t4 - CLOSE\n"); printf( "5 - UNLINK\t6 - GETVALUE\t7 - TRYWAIT\t8 - INIT\n"); printf( "9 - DESTROY\t10 - FREE SPACE\n"); if ( get_num(&opt) == -1 ) { hasEnded = 1; continue; } putchar('\n'); switch (opt) { case 1: m_open(); break; case 2: m_wait(); break; case 3: m_post(); break; case 4: m_close(); break; case 5: m_unlink(); break; case 6: m_getvalue(); break; case 7: m_trywait(); break; case 8: m_sem_init(); break; case 9: m_destroy(); break; case 10: free_space(); break; default: printf("Opcion invalida\n"); } } }
static void simple_set(struct ybc *const cache, const size_t requests_count, const size_t items_count, const size_t max_item_size) { struct m_rand_state rand_state; uint64_t tmp; char *const buf = p_malloc(max_item_size); const struct ybc_key key = { .ptr = &tmp, .size = sizeof(tmp), }; struct ybc_value value = { .ptr = buf, .size = 0, .ttl = YBC_MAX_TTL, }; m_rand_init(&rand_state); for (size_t i = 0; i < requests_count; ++i) { tmp = m_rand_next(&rand_state) % items_count; value.size = m_rand_next(&rand_state) % (max_item_size + 1); m_memset(buf, (char)value.size, value.size); if (!ybc_item_set(cache, &key, &value)) { M_ERROR("Cannot store item in the cache"); } } free(buf); } static void simple_get_miss(struct ybc *const cache, const size_t requests_count, const size_t items_count) { char item_buf[ybc_item_get_size()]; struct ybc_item *const item = (struct ybc_item *)item_buf; struct m_rand_state rand_state; uint64_t tmp; const struct ybc_key key = { .ptr = &tmp, .size = sizeof(tmp), }; m_rand_init(&rand_state); for (size_t i = 0; i < requests_count; ++i) { tmp = m_rand_next(&rand_state) % items_count; if (ybc_item_get(cache, item, &key)) { M_ERROR("Unexpected item found"); } } } static void simple_get_hit(struct ybc *const cache, const size_t requests_count, const size_t items_count, const size_t max_item_size) { char item_buf[ybc_item_get_size()]; struct ybc_item *const item = (struct ybc_item *)item_buf; struct m_rand_state rand_state; uint64_t tmp; const struct ybc_key key = { .ptr = &tmp, .size = sizeof(tmp), }; struct ybc_value value; m_rand_init(&rand_state); for (size_t i = 0; i < requests_count; ++i) { tmp = m_rand_next(&rand_state) % items_count; if (ybc_item_get(cache, item, &key)) { /* Emulate access to the item */ ybc_item_get_value(item, &value); if (value.size > max_item_size) { M_ERROR("Unexpected value size"); } if (!m_memset_check(value.ptr, (char)value.size, value.size)) { fprintf(stderr, "i=%zu, requests_count=%zu, value.size=%zu\n", i, requests_count, value.size); M_ERROR("Unexpected value"); } ybc_item_release(item); } } } static void m_open(struct ybc *const cache, const size_t items_count, const size_t hot_items_count, const size_t max_item_size) { char config_buf[ybc_config_get_size()]; struct ybc_config *const config = (struct ybc_config *)config_buf; const size_t data_file_size = max_item_size * items_count; const size_t hot_data_size = max_item_size * hot_items_count; ybc_config_init(config); ybc_config_set_max_items_count(config, items_count); ybc_config_set_hot_items_count(config, hot_items_count); ybc_config_set_data_file_size(config, data_file_size); ybc_config_set_hot_data_size(config, hot_data_size); if (!ybc_open(cache, config, 1)) { M_ERROR("Cannot create a cache"); } ybc_config_destroy(config); } static void measure_simple_ops(struct ybc *const cache, const size_t requests_count, const size_t items_count, const size_t hot_items_count, const size_t max_item_size) { double start_time, end_time; double qps; m_open(cache, items_count, hot_items_count, max_item_size); printf("simple_ops(requests=%zu, items=%zu, " "hot_items=%zu, max_item_size=%zu)\n", requests_count, items_count, hot_items_count, max_item_size); start_time = p_get_current_time(); simple_get_miss(cache, requests_count, items_count); end_time = p_get_current_time(); qps = requests_count / (end_time - start_time) * 1000; printf(" get_miss: %.02f qps\n", qps); start_time = p_get_current_time(); simple_set(cache, requests_count, items_count, max_item_size); end_time = p_get_current_time(); qps = requests_count / (end_time - start_time) * 1000; printf(" set : %.02f qps\n", qps); const size_t get_items_count = hot_items_count ? hot_items_count : items_count; start_time = p_get_current_time(); simple_get_hit(cache, requests_count, get_items_count, max_item_size); end_time = p_get_current_time(); qps = requests_count / (end_time - start_time) * 1000; printf(" get_hit : %.02f qps\n", qps); ybc_close(cache); }
static void measure_multithreaded_ops(struct ybc *const cache, const size_t threads_count, const size_t requests_count, const size_t items_count, const size_t hot_items_count, const size_t max_item_size) { double qps; m_open(cache, items_count, hot_items_count, max_item_size); struct thread_task task = { .cache = cache, .items_count = items_count, .get_items_count = hot_items_count ? hot_items_count : items_count, .max_item_size = max_item_size, }; p_lock_init(&task.lock); printf("multithreaded_ops(requests=%zu, items=%zu, hot_items=%zu, " "max_item_size=%zu, threads=%zu)\n", requests_count, items_count, hot_items_count, max_item_size, threads_count); qps = measure_qps(&task, thread_func_get_miss, threads_count, requests_count); printf(" get_miss: %.2f qps\n", qps); qps = measure_qps(&task, thread_func_set, threads_count, requests_count); printf(" set : %.2f qps\n", qps); qps = measure_qps(&task, thread_func_get_hit, threads_count, requests_count); printf(" get_hit : %.2f qps\n", qps); qps = measure_qps(&task, thread_func_set_get, threads_count, requests_count); printf(" get_set : %.2f qps\n", qps); p_lock_destroy(&task.lock); ybc_close(cache); } int main(void) { char cache_buf[ybc_get_size()]; struct ybc *const cache = (struct ybc *)cache_buf; const size_t requests_count = 4 * 1000 * 1000; const size_t items_count = 200 * 1000; for (size_t max_item_size = 8; max_item_size <= 4096; max_item_size *= 2) { measure_simple_ops(cache, requests_count, items_count, 0, max_item_size); for (size_t hot_items_count = 1000; hot_items_count <= items_count; hot_items_count *= 10) { measure_simple_ops(cache, requests_count, items_count, hot_items_count, max_item_size); } for (size_t threads_count = 1; threads_count <= 16; threads_count *= 2) { measure_multithreaded_ops(cache, threads_count, requests_count, items_count, 10 * 1000, max_item_size); } } printf("All performance tests done\n"); return 0; }
static void simple_set(struct ybc *const cache, const size_t requests_count, const size_t items_count, const size_t max_item_size) { struct m_rand_state rand_state; uint64_t tmp; char *const buf = p_malloc(max_item_size); const struct ybc_key key = { .ptr = &tmp, .size = sizeof(tmp), }; struct ybc_value value = { .ptr = buf, .size = 0, .ttl = YBC_MAX_TTL, }; m_rand_init(&rand_state); for (size_t i = 0; i < requests_count; ++i) { tmp = m_rand_next(&rand_state) % items_count; value.size = m_rand_next(&rand_state) % (max_item_size + 1); m_memset(buf, (char)value.size, value.size); if (!ybc_item_set(cache, &key, &value)) { M_ERROR("Cannot store item in the cache"); } } p_free(buf); } static void simple_set_simple(struct ybc *const cache, const size_t requests_count, const size_t items_count, const size_t max_item_size) { struct m_rand_state rand_state; uint64_t tmp; char *const buf = p_malloc(max_item_size); const struct ybc_key key = { .ptr = &tmp, .size = sizeof(tmp), }; struct ybc_value value = { .ptr = buf, .size = 0, .ttl = YBC_MAX_TTL, }; m_rand_init(&rand_state); for (size_t i = 0; i < requests_count; ++i) { tmp = m_rand_next(&rand_state) % items_count; value.size = m_rand_next(&rand_state) % (max_item_size + 1); m_memset(buf, (char)value.size, value.size); if (!ybc_simple_set(cache, &key, &value)) { M_ERROR("Cannot store item in the cache"); } } p_free(buf); } static void simple_get_miss(struct ybc *const cache, const size_t requests_count, const size_t items_count) { char item_buf[ybc_item_get_size()]; struct ybc_item *const item = (struct ybc_item *)item_buf; struct m_rand_state rand_state; uint64_t tmp; const struct ybc_key key = { .ptr = &tmp, .size = sizeof(tmp), }; m_rand_init(&rand_state); for (size_t i = 0; i < requests_count; ++i) { tmp = m_rand_next(&rand_state) % items_count; if (ybc_item_get(cache, item, &key)) { M_ERROR("Unexpected item found"); } } } static void simple_get_hit(struct ybc *const cache, const size_t requests_count, const size_t items_count, const size_t max_item_size) { char item_buf[ybc_item_get_size()]; struct ybc_item *const item = (struct ybc_item *)item_buf; struct m_rand_state rand_state; uint64_t tmp; const struct ybc_key key = { .ptr = &tmp, .size = sizeof(tmp), }; struct ybc_value value; m_rand_init(&rand_state); for (size_t i = 0; i < requests_count; ++i) { tmp = m_rand_next(&rand_state) % items_count; if (ybc_item_get(cache, item, &key)) { /* Emulate access to the item */ ybc_item_get_value(item, &value); if (value.size > max_item_size) { M_ERROR("Unexpected value size"); } if (!m_memset_check(value.ptr, (char)value.size, value.size)) { fprintf(stderr, "i=%zu, requests_count=%zu, value.size=%zu\n", i, requests_count, value.size); M_ERROR("Unexpected value"); } ybc_item_release(item); } } } static void simple_get_simple_hit(struct ybc *const cache, const size_t requests_count, const size_t items_count, const size_t max_item_size) { struct m_rand_state rand_state; uint64_t tmp; const struct ybc_key key = { .ptr = &tmp, .size = sizeof(tmp), }; struct ybc_value value; value.size = max_item_size; value.ptr = p_malloc(value.size); m_rand_init(&rand_state); for (size_t i = 0; i < requests_count; ++i) { tmp = m_rand_next(&rand_state) % items_count; value.size = max_item_size; int rv = ybc_simple_get(cache, &key, &value); if (rv == 0) { continue; } assert(rv == 1); if (value.size > max_item_size) { M_ERROR("Unexpected value size"); } if (!m_memset_check(value.ptr, (char)value.size, value.size)) { fprintf(stderr, "i=%zu, requests_count=%zu, value.size=%zu\n", i, requests_count, value.size); M_ERROR("Unexpected value"); } } p_free((void *)value.ptr); } static void m_open(struct ybc *const cache, const int use_shm, const size_t items_count, const size_t hot_items_count, const size_t max_item_size, const int has_overwrite_protection) { char config_buf[ybc_config_get_size()]; struct ybc_config *const config = (struct ybc_config *)config_buf; const size_t data_file_size = max_item_size * items_count; const size_t hot_data_size = max_item_size * hot_items_count; ybc_config_init(config); if (use_shm) { ybc_config_set_data_file(config, "/dev/shm/ybc-perftest-cache.data"); ybc_config_set_index_file(config, "/dev/shm/ybc-perftest-cache.index"); } ybc_config_set_max_items_count(config, items_count); ybc_config_set_hot_items_count(config, hot_items_count); ybc_config_set_data_file_size(config, data_file_size); ybc_config_set_hot_data_size(config, hot_data_size); if (!has_overwrite_protection) { ybc_config_disable_overwrite_protection(config); } if (!ybc_open(cache, config, 1)) { M_ERROR("Cannot create a cache"); } ybc_config_destroy(config); if (use_shm) { ybc_clear(cache); } } static void m_close(struct ybc *const cache, const int use_shm) { ybc_close(cache); if (!use_shm) { return; } char config_buf[ybc_config_get_size()]; struct ybc_config *const config = (struct ybc_config *)config_buf; ybc_config_init(config); ybc_config_set_data_file(config, "/dev/shm/ybc-perftest-cache.data"); ybc_config_set_index_file(config, "/dev/shm/ybc-perftest-cache.index"); ybc_remove(config); ybc_config_destroy(config); } static void measure_simple_ops(struct ybc *const cache, const int use_shm, const size_t requests_count, const size_t items_count, const size_t hot_items_count, const size_t max_item_size, const int has_overwrite_protection) { double start_time, end_time; double qps; m_open(cache, use_shm, items_count, hot_items_count, max_item_size, has_overwrite_protection); printf("simple_ops(requests=%zu, items=%zu, " "hot_items=%zu, max_item_size=%zu, has_overwrite_protection=%d, use_shm=%d)\n", requests_count, items_count, hot_items_count, max_item_size, has_overwrite_protection, use_shm); start_time = p_get_current_time(); simple_get_miss(cache, requests_count, items_count); end_time = p_get_current_time(); qps = requests_count / (end_time - start_time) * 1000; printf(" get_miss : %.02f qps\n", qps); start_time = p_get_current_time(); simple_set(cache, requests_count, items_count, max_item_size); end_time = p_get_current_time(); qps = requests_count / (end_time - start_time) * 1000; printf(" set : %.02f qps\n", qps); const size_t get_items_count = hot_items_count ? hot_items_count : items_count; if (has_overwrite_protection) { start_time = p_get_current_time(); simple_get_hit(cache, requests_count, get_items_count, max_item_size); end_time = p_get_current_time(); qps = requests_count / (end_time - start_time) * 1000; printf(" get_hit : %.02f qps\n", qps); } ybc_clear(cache); start_time = p_get_current_time(); simple_set_simple(cache, requests_count, items_count, max_item_size); end_time = p_get_current_time(); qps = requests_count / (end_time - start_time) * 1000; printf(" set_simple : %.02f qps\n", qps); start_time = p_get_current_time(); simple_get_simple_hit(cache, requests_count, get_items_count, max_item_size); end_time = p_get_current_time(); qps = requests_count / (end_time - start_time) * 1000; printf(" get_simple_hit : %.02f qps\n", qps); m_close(cache, use_shm); } struct thread_task { struct p_lock lock; struct ybc *cache; size_t requests_count; size_t items_count; size_t get_items_count; size_t max_item_size; }; static size_t get_batch_requests_count(struct thread_task *const task) { static const size_t batch_requests_count = 10000; size_t requests_count = batch_requests_count; p_lock_lock(&task->lock); if (task->requests_count < batch_requests_count) { requests_count = task->requests_count; } task->requests_count -= requests_count; p_lock_unlock(&task->lock); return requests_count; } static void thread_func_set(void *const ctx) { struct thread_task *const task = ctx; for (;;) { const size_t requests_count = get_batch_requests_count(task); if (requests_count == 0) { break; } simple_set(task->cache, requests_count, task->items_count, task->max_item_size); } } static void thread_func_get_miss(void *const ctx) { struct thread_task *const task = ctx; for (;;) { const size_t requests_count = get_batch_requests_count(task); if (requests_count == 0) { break; } simple_get_miss(task->cache, requests_count, task->get_items_count); } } static void thread_func_get_hit(void *const ctx) { struct thread_task *const task = ctx; for (;;) { const size_t requests_count = get_batch_requests_count(task); if (requests_count == 0) { break; } simple_get_hit(task->cache, requests_count, task->get_items_count, task->max_item_size); } } static void thread_func_set_get(void *const ctx) { struct thread_task *const task = ctx; for (;;) { const size_t requests_count = get_batch_requests_count(task); if (requests_count == 0) { break; } const size_t set_requests_count = (size_t)(requests_count * 0.1); const size_t get_requests_count = requests_count - set_requests_count; simple_set(task->cache, set_requests_count, task->items_count, task->max_item_size); simple_get_hit(task->cache, get_requests_count, task->get_items_count, task->max_item_size); } } static void thread_func_set_simple(void *const ctx) { struct thread_task *const task = ctx; for (;;) { const size_t requests_count = get_batch_requests_count(task); if (requests_count == 0) { break; } simple_set_simple(task->cache, requests_count, task->items_count, task->max_item_size); } } static void thread_func_get_simple_hit(void *const ctx) { struct thread_task *const task = ctx; for (;;) { const size_t requests_count = get_batch_requests_count(task); if (requests_count == 0) { break; } simple_get_simple_hit(task->cache, requests_count, task->get_items_count, task->max_item_size); } } static double measure_qps(struct thread_task *const task, const p_thread_func thread_func, const size_t threads_count, const size_t requests_count) { struct p_thread threads[threads_count]; task->requests_count = requests_count; double start_time = p_get_current_time(); for (size_t i = 0; i < threads_count; ++i) { p_thread_init_and_start(&threads[i], thread_func, task); } for (size_t i = 0; i < threads_count; ++i) { p_thread_join_and_destroy(&threads[i]); } double end_time = p_get_current_time(); return requests_count / (end_time - start_time) * 1000; } static void measure_multithreaded_ops(struct ybc *const cache, const int use_shm, const size_t threads_count, const size_t requests_count, const size_t items_count, const size_t hot_items_count, const size_t max_item_size, const int has_overwrite_protection) { double qps; m_open(cache, use_shm, items_count, hot_items_count, max_item_size, has_overwrite_protection); struct thread_task task = { .cache = cache, .items_count = items_count, .get_items_count = hot_items_count ? hot_items_count : items_count, .max_item_size = max_item_size, }; p_lock_init(&task.lock); printf("multithreaded_ops(requests=%zu, items=%zu, hot_items=%zu, " "max_item_size=%zu, threads=%zu, has_overwrite_protection=%d, use_shm=%d)\n", requests_count, items_count, hot_items_count, max_item_size, threads_count, has_overwrite_protection, use_shm); qps = measure_qps(&task, thread_func_get_miss, threads_count, requests_count); printf(" get_miss : %.2f qps\n", qps); qps = measure_qps(&task, thread_func_set, threads_count, requests_count); printf(" set : %.2f qps\n", qps); if (has_overwrite_protection) { qps = measure_qps(&task, thread_func_get_hit, threads_count, requests_count); printf(" get_hit : %.2f qps\n", qps); qps = measure_qps(&task, thread_func_set_get, threads_count, requests_count); printf(" get_set : %.2f qps\n", qps); } ybc_clear(cache); qps = measure_qps(&task, thread_func_set_simple, threads_count, requests_count); printf(" set_simple : %.2f qps\n", qps); qps = measure_qps(&task, thread_func_get_simple_hit, threads_count, requests_count); printf(" get_simple_hit : %.2f qps\n", qps); p_lock_destroy(&task.lock); m_close(cache, use_shm); } int main(void) { char cache_buf[ybc_get_size()]; struct ybc *const cache = (struct ybc *)cache_buf; const size_t requests_count = 4 * 1000 * 1000; const size_t items_count = 200 * 1000; for (size_t max_item_size = 8; max_item_size <= 4096; max_item_size *= 2) { measure_simple_ops(cache, 0, requests_count, items_count, 0, max_item_size, 0); measure_simple_ops(cache, 0, requests_count, items_count, 0, max_item_size, 1); measure_simple_ops(cache, 1, requests_count, items_count, 0, max_item_size, 0); measure_simple_ops(cache, 1, requests_count, items_count, 0, max_item_size, 1); for (size_t hot_items_count = 1000; hot_items_count <= items_count; hot_items_count *= 10) { measure_simple_ops(cache, 0, requests_count, items_count, hot_items_count, max_item_size, 0); measure_simple_ops(cache, 0, requests_count, items_count, hot_items_count, max_item_size, 1); measure_simple_ops(cache, 1, requests_count, items_count, hot_items_count, max_item_size, 0); measure_simple_ops(cache, 1, requests_count, items_count, hot_items_count, max_item_size, 1); } for (size_t threads_count = 1; threads_count <= 16; threads_count *= 2) { measure_multithreaded_ops(cache, 0, threads_count, requests_count, items_count, 10 * 1000, max_item_size, 0); measure_multithreaded_ops(cache, 0, threads_count, requests_count, items_count, 10 * 1000, max_item_size, 1); measure_multithreaded_ops(cache, 1, threads_count, requests_count, items_count, 10 * 1000, max_item_size, 0); measure_multithreaded_ops(cache, 1, threads_count, requests_count, items_count, 10 * 1000, max_item_size, 1); } } printf("All performance tests done\n"); return 0; }