Blame test/allocator_perf_tool/main.cpp

Packit 345191
/*
Packit 345191
* Copyright (C) 2015 - 2018 Intel Corporation.
Packit 345191
* All rights reserved.
Packit 345191
*
Packit 345191
* Redistribution and use in source and binary forms, with or without
Packit 345191
* modification, are permitted provided that the following conditions are met:
Packit 345191
* 1. Redistributions of source code must retain the above copyright notice(s),
Packit 345191
*    this list of conditions and the following disclaimer.
Packit 345191
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
Packit 345191
*    this list of conditions and the following disclaimer in the documentation
Packit 345191
*    and/or other materials provided with the distribution.
Packit 345191
*
Packit 345191
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
Packit 345191
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
Packit 345191
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
Packit 345191
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit 345191
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 345191
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 345191
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 345191
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
Packit 345191
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Packit 345191
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 345191
*/
Packit 345191
Packit 345191
#include <stdio.h>
Packit 345191
#include <assert.h>
Packit 345191
#include <iostream>
Packit 345191
#include <vector>
Packit 345191
Packit 345191
#include "Configuration.hpp"
Packit 345191
#include "AllocatorFactory.hpp"
Packit 345191
#include "TaskFactory.hpp"
Packit 345191
#include "Task.hpp"
Packit 345191
#include "ConsoleLog.hpp"
Packit 345191
#include "Stats.hpp"
Packit 345191
#include "Thread.hpp"
Packit 345191
#include "Tests.hpp"
Packit 345191
#include "CommandLine.hpp"
Packit 345191
#include "FunctionCallsPerformanceTask.h"
Packit 345191
#include "StressIncreaseToMax.h"
Packit 345191
Packit 345191
/*
Packit 345191
Command line description.
Packit 345191
Syntax:
Packit 345191
	key=value
Packit 345191
Options:
Packit 345191
	- 'test' - specify the test case. This option can be used with the following values: 'calls', 'all' or 'self',
Packit 345191
	where:
Packit 345191
		'calls' - function calls performance test,
Packit 345191
		'all' - execute both above ('footprint' and 'calls') tests,
Packit 345191
		'self' - execute self tests
Packit 345191
		's1' - stress tests
Packit 345191
		(perform allocations until the maximum amount of allocated memory has been reached, than frees allocated memory.
Packit 345191
		If the time interval has not been exceed, than repeat the test),
Packit 345191
	- 'operations' - the number of memory operations per thread
Packit 345191
	- 'size_from' - lower bound for the random sizes of allocation
Packit 345191
	- 'size_to' - upper bound for the random sizes of allocation
Packit 345191
	- 'seed' - random seed
Packit 345191
	- 'threads_num' - the number of threads per test case
Packit 345191
	- 'time' - minimum execution time interval
Packit 345191
	- 'kind' - the kind to test
Packit 345191
	- 'csv_log' - if 'true' then log to csv file memory operations and statistics
Packit 345191
	- 'call' specify the allocation function call. This option can be used with the following values: 'malloc' (default), 'calloc', 'realloc',
Packit 345191
	- 'requested_memory_limit' test stops when the requested memory limit has been reached
Packit 345191
* - maximum of available memory in OS, or maximum memory based 'operations' parameter
Packit 345191
Example:
Packit 345191
1. Performance test:
Packit 345191
./perf_tool test=all operations=1000 size_from=32 size_to=20480 seed=11 threads_num=200
Packit 345191
2. Stress test
Packit 345191
./perf_tool test=s1 time=120 kind=MEMKIND_HBW size_from=1048576 csv_log=true requested_memory_limit=1048576
Packit 345191
*/
Packit 345191
Packit 345191
int main(int argc, char *argv[])
Packit 345191
{
Packit 345191
    unsigned mem_operations_num = 1000;
Packit 345191
    size_t size_from = 32, size_to = 2048*1024;
Packit 345191
    unsigned seed = 11;
Packit 345191
    //should be at least one
Packit 345191
    size_t threads_number = 10;
Packit 345191
Packit 345191
    CommandLine cmd_line(argc, argv);
Packit 345191
Packit 345191
    if((argc >= 1) && cmd_line.is_option_set("test", "self")) {
Packit 345191
        execute_self_tests();
Packit 345191
        getchar();
Packit 345191
    }
Packit 345191
Packit 345191
    cmd_line.parse_with_strtol("operations", mem_operations_num);
Packit 345191
    cmd_line.parse_with_strtol("size_from", size_from);
Packit 345191
    cmd_line.parse_with_strtol("size_to", size_to);
Packit 345191
    cmd_line.parse_with_strtol("seed", seed);
Packit 345191
    cmd_line.parse_with_strtol("threads_num", threads_number);
Packit 345191
Packit 345191
    bool is_csv_log_enabled = cmd_line.is_option_set("csv_log", "true");
Packit 345191
Packit 345191
    //Heap Manager initialization
Packit 345191
    std::vector<AllocatorFactory::initialization_stat> stats =
Packit 345191
        AllocatorFactory().initialization_test();
Packit 345191
Packit 345191
    if(!cmd_line.is_option_set("print_init_stats", "false")) {
Packit 345191
        printf("\nInitialization overhead:\n");
Packit 345191
        for (int i=0; i
Packit 345191
            AllocatorFactory::initialization_stat stat = stats[i];
Packit 345191
            printf("%32s : time=%7.7f.s, ref_delta_time=%15f, node0=%10fMB, node1=%7.7fMB\n",
Packit 345191
                   AllocatorTypes::allocator_name(stat.allocator_type).c_str(),
Packit 345191
                   stat.total_time,
Packit 345191
                   stat.ref_delta_time,
Packit 345191
                   stat.memory_overhead[0],
Packit 345191
                   stat.memory_overhead[1]);
Packit 345191
        }
Packit 345191
    }
Packit 345191
Packit 345191
    //Stress test by repeatedly increasing memory (to maximum), until given time interval has been exceed.
Packit 345191
    if(cmd_line.is_option_set("test", "s1")) {
Packit 345191
        printf("Stress test (StressIncreaseToMax) start. \n");
Packit 345191
Packit 345191
        if(!cmd_line.is_option_present("operations"))
Packit 345191
            mem_operations_num = 1000000;
Packit 345191
Packit 345191
        unsigned time = 120; //Default time interval.
Packit 345191
        cmd_line.parse_with_strtol("time", time);
Packit 345191
Packit 345191
        size_t requested_memory_limit = 1024*1024;
Packit 345191
        cmd_line.parse_with_strtol("requested_memory_limit", requested_memory_limit);
Packit 345191
Packit 345191
        unsigned allocator = AllocatorTypes::MEMKIND_HBW;
Packit 345191
        if(cmd_line.is_option_present("kind")) {
Packit 345191
            //Enable memkind allocator and specify kind.
Packit 345191
            allocator = AllocatorTypes::allocator_type(cmd_line.get_option_value("kind"));
Packit 345191
        }
Packit 345191
        TypesConf allocator_types;
Packit 345191
        allocator_types.enable_type(allocator);
Packit 345191
Packit 345191
        TypesConf enable_func_calls;
Packit 345191
        enable_func_calls.enable_type(FunctionCalls::MALLOC);
Packit 345191
Packit 345191
        TaskConf task_conf = {
Packit 345191
            mem_operations_num,
Packit 345191
            {
Packit 345191
                mem_operations_num,
Packit 345191
                size_from, //No random sizes.
Packit 345191
                size_from
Packit 345191
            },
Packit 345191
            enable_func_calls,
Packit 345191
            allocator_types,
Packit 345191
            11,
Packit 345191
            is_csv_log_enabled,
Packit 345191
        };
Packit 345191
Packit 345191
        StressIncreaseToMax::execute_test_iterations(task_conf, time,
Packit 345191
                                                     requested_memory_limit);
Packit 345191
        return 0;
Packit 345191
    }
Packit 345191
Packit 345191
    printf("\nTest configuration: \n");
Packit 345191
    printf("\t memory operations per thread = %u \n", mem_operations_num);
Packit 345191
    printf("\t seed = %d\n", seed);
Packit 345191
    printf("\t number of threads = %zu\n", threads_number);
Packit 345191
    printf("\t size from-to = %zu-%zu\n\n", size_from, size_to);
Packit 345191
Packit 345191
    assert(size_from <= size_to);
Packit 345191
Packit 345191
Packit 345191
    TypesConf func_calls;
Packit 345191
    func_calls.enable_type(FunctionCalls::FREE);
Packit 345191
Packit 345191
    if(cmd_line.is_option_present("call")) {
Packit 345191
        //Enable heap manager function call.
Packit 345191
        func_calls.enable_type(FunctionCalls::function_type(
Packit 345191
                                   cmd_line.get_option_value("call")));
Packit 345191
    } else {
Packit 345191
        func_calls.enable_type(FunctionCalls::MALLOC);
Packit 345191
    }
Packit 345191
Packit 345191
    TypesConf allocator_types;
Packit 345191
    if(cmd_line.is_option_present("allocator")) {
Packit 345191
        allocator_types.enable_type(AllocatorTypes::allocator_type(
Packit 345191
                                        cmd_line.get_option_value("allocator")));
Packit 345191
    } else {
Packit 345191
        for(unsigned i = 0; i <= AllocatorTypes::MEMKIND_HBW_PREFERRED; i++) {
Packit 345191
            allocator_types.enable_type(i);
Packit 345191
        }
Packit 345191
    }
Packit 345191
Packit 345191
    TaskConf conf = {
Packit 345191
        mem_operations_num, //number memory operations
Packit 345191
        {
Packit 345191
            mem_operations_num, //number of memory operations
Packit 345191
            size_from, //min. size of single allocation
Packit 345191
            size_to //max. size of single allocatioion
Packit 345191
        },
Packit 345191
        func_calls, //enable function calls
Packit 345191
        allocator_types, //enable allocators
Packit 345191
        seed, //random seed
Packit 345191
        is_csv_log_enabled,
Packit 345191
    };
Packit 345191
Packit 345191
    //Function calls test
Packit 345191
    if(cmd_line.is_option_set("test", "calls") ||
Packit 345191
       cmd_line.is_option_set("test", "all")) {
Packit 345191
        TaskFactory task_factory;
Packit 345191
        std::vector<Thread *> threads;
Packit 345191
        std::vector<Task *> tasks;
Packit 345191
Packit 345191
        for (int i=0; i
Packit 345191
            FunctionCallsPerformanceTask *task =
Packit 345191
                static_cast<FunctionCallsPerformanceTask *>(
Packit 345191
                    task_factory.create(conf)
Packit 345191
                );
Packit 345191
            tasks.push_back(task);
Packit 345191
            threads.push_back(new Thread(task));
Packit 345191
            conf.seed += 1;
Packit 345191
        }
Packit 345191
Packit 345191
        ThreadsManager threads_manager(threads);
Packit 345191
        threads_manager.start();
Packit 345191
        threads_manager.barrier();
Packit 345191
Packit 345191
        TimeStats stats;
Packit 345191
        for (int i=0; i
Packit 345191
            stats += tasks[i]->get_results();
Packit 345191
        }
Packit 345191
Packit 345191
        ConsoleLog::print_table(stats);
Packit 345191
        ConsoleLog::print_requested_memory(stats, "func. calls test");
Packit 345191
Packit 345191
        threads_manager.release();
Packit 345191
    }
Packit 345191
Packit 345191
    return 0;
Packit 345191
}