Blame test/performance/operations.hpp

Packit Service 724aca
/*
Packit Service 724aca
* Copyright (C) 2014 - 2018 Intel Corporation.
Packit Service 724aca
* All rights reserved.
Packit Service 724aca
*
Packit Service 724aca
* Redistribution and use in source and binary forms, with or without
Packit Service 724aca
* modification, are permitted provided that the following conditions are met:
Packit Service 724aca
* 1. Redistributions of source code must retain the above copyright notice(s),
Packit Service 724aca
*    this list of conditions and the following disclaimer.
Packit Service 724aca
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
Packit Service 724aca
*    this list of conditions and the following disclaimer in the documentation
Packit Service 724aca
*    and/or other materials provided with the distribution.
Packit Service 724aca
*
Packit Service 724aca
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
Packit Service 724aca
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
Packit Service 724aca
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
Packit Service 724aca
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit Service 724aca
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit Service 724aca
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit Service 724aca
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit Service 724aca
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
Packit Service 724aca
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Packit Service 724aca
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 724aca
*/
Packit Service 724aca
Packit Service 724aca
#pragma once
Packit Service 724aca
Packit Service 724aca
#include <memkind.h>
Packit Service 724aca
Packit Service 724aca
#include <malloc.h>
Packit Service 724aca
#include <cassert>
Packit Service 724aca
#include "jemalloc/jemalloc.h"
Packit Service 724aca
Packit Service 724aca
// Malloc, jemalloc, memkind jemalloc and memkind memory operations definitions
Packit Service 724aca
namespace performance_tests
Packit Service 724aca
{
Packit Service 724aca
    using std::vector;
Packit Service 724aca
    using std::string;
Packit Service 724aca
    using std::thread;
Packit Service 724aca
Packit Service 724aca
#ifdef __DEBUG
Packit Service 724aca
#include <mutex>
Packit Service 724aca
    // Write entire text at once, avoiding switching to another thread
Packit Service 724aca
    extern int g_msgLevel;
Packit Service 724aca
    extern std::mutex g_coutMutex;
Packit Service 724aca
#define EMIT(LEVEL, TEXT) \
Packit Service 724aca
    if (g_msgLevel >= LEVEL) \
Packit Service 724aca
    { \
Packit Service 724aca
        g_coutMutex.lock(); std::cout << TEXT << std::endl; g_coutMutex.unlock(); \
Packit Service 724aca
    }
Packit Service 724aca
#else
Packit Service 724aca
#define EMIT(LEVEL, TEXT)
Packit Service 724aca
#endif
Packit Service 724aca
Packit Service 724aca
    // Use jemalloc, compiled with unique prefix (--with-jemalloc-prefix= configure option)
Packit Service 724aca
#ifdef SYSTEM_JEMALLOC_PREFIX
Packit Service 724aca
#define TOKENPASTE(x, y) x ## y
Packit Service 724aca
#define JE(x, y) TOKENPASTE(x, y)
Packit Service 724aca
#define jexx_malloc JE(SYSTEM_JEMALLOC_PREFIX, malloc)
Packit Service 724aca
#define jexx_calloc JE(SYSTEM_JEMALLOC_PREFIX, calloc)
Packit Service 724aca
#define jexx_memalign JE(SYSTEM_JEMALLOC_PREFIX, memalign)
Packit Service 724aca
#define jexx_realloc JE(SYSTEM_JEMALLOC_PREFIX, realloc)
Packit Service 724aca
#define jexx_free JE(SYSTEM_JEMALLOC_PREFIX, free)
Packit Service 724aca
    extern "C" {
Packit Service 724aca
        // jemalloc function prototypes
Packit Service 724aca
        // full header cannot be include due to conflict with memkind jemalloc
Packit Service 724aca
        extern void *jexx_malloc(size_t size);
Packit Service 724aca
        extern void *jexx_calloc(size_t num, size_t size);
Packit Service 724aca
        extern void *jexx_memalign(size_t alignment, size_t size);
Packit Service 724aca
        extern void *jexx_realloc(void *ptr, size_t size);
Packit Service 724aca
        extern void  jexx_free(void *ptr);
Packit Service 724aca
    }
Packit Service 724aca
#endif
Packit Service 724aca
Packit Service 724aca
    // Available memory operations
Packit Service 724aca
    enum OperationName {
Packit Service 724aca
        Malloc,
Packit Service 724aca
        Calloc,
Packit Service 724aca
        Realloc,
Packit Service 724aca
        Align,
Packit Service 724aca
        Free,
Packit Service 724aca
        Invalid
Packit Service 724aca
    };
Packit Service 724aca
Packit Service 724aca
    // Reprents a memory operation
Packit Service 724aca
    class Operation
Packit Service 724aca
    {
Packit Service 724aca
    public:
Packit Service 724aca
        // Each operation is assigned a bucket size from range (0, MaxBucketSize)
Packit Service 724aca
        static const unsigned MaxBucketSize = 100;
Packit Service 724aca
        // For memalign operation, alignment parameter will be a random value
Packit Service 724aca
        // from range (sizeof(void*), sizeof(void*) * MemalignMaxMultiplier)
Packit Service 724aca
        static const unsigned MemalignMaxMultiplier = 4;
Packit Service 724aca
Packit Service 724aca
    protected:
Packit Service 724aca
        OperationName m_name;
Packit Service 724aca
        // If random number from range (0, MaxBucketSize) is lower than m_bucketSize, an operation will be performed
Packit Service 724aca
        unsigned m_bucketSize;
Packit Service 724aca
Packit Service 724aca
    public:
Packit Service 724aca
        Operation()
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        // Creates an operation with given name and bucket size
Packit Service 724aca
        // If no bucket size is given, operation will be always performed
Packit Service 724aca
        Operation(
Packit Service 724aca
            OperationName name,
Packit Service 724aca
            unsigned bucketSize = MaxBucketSize)
Packit Service 724aca
            : m_name(name)
Packit Service 724aca
            , m_bucketSize(bucketSize)
Packit Service 724aca
        {
Packit Service 724aca
            assert(bucketSize <= MaxBucketSize);
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        virtual ~Operation() {}
Packit Service 724aca
        ;
Packit Service 724aca
Packit Service 724aca
        // Check if operation should be performed (currently drawn random number lower than bucket size)
Packit Service 724aca
        bool checkCondition(unsigned ballSize) const
Packit Service 724aca
        {
Packit Service 724aca
            return (ballSize < m_bucketSize);
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        OperationName getName() const
Packit Service 724aca
        {
Packit Service 724aca
            return m_name;
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        string getNameStr() const
Packit Service 724aca
        {
Packit Service 724aca
            switch (m_name) {
Packit Service 724aca
                case OperationName::Malloc:
Packit Service 724aca
                    return "malloc";
Packit Service 724aca
Packit Service 724aca
                case OperationName::Calloc:
Packit Service 724aca
                    return "calloc";
Packit Service 724aca
Packit Service 724aca
                case OperationName::Realloc:
Packit Service 724aca
                    return "realloc";
Packit Service 724aca
Packit Service 724aca
                case OperationName::Align:
Packit Service 724aca
                    return "align";
Packit Service 724aca
Packit Service 724aca
                case OperationName::Free:
Packit Service 724aca
                    return "free";
Packit Service 724aca
Packit Service 724aca
                default:
Packit Service 724aca
                    return "<unknown>";
Packit Service 724aca
            }
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        // Get operation bucket size
Packit Service 724aca
        unsigned getBucketSize() const
Packit Service 724aca
        {
Packit Service 724aca
            return m_bucketSize;
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        // perform memory operation
Packit Service 724aca
        virtual void perform(const memkind_t &kind,
Packit Service 724aca
                             void *&mem,
Packit Service 724aca
                             size_t size = 0,
Packit Service 724aca
                             size_t offset=0,
Packit Service 724aca
                             size_t alignment=0)
Packit Service 724aca
        const = 0;
Packit Service 724aca
Packit Service 724aca
    };
Packit Service 724aca
Packit Service 724aca
    // Malloc memory operations
Packit Service 724aca
    class MallocOperation : public Operation
Packit Service 724aca
    {
Packit Service 724aca
    public:
Packit Service 724aca
        MallocOperation(
Packit Service 724aca
            OperationName name)
Packit Service 724aca
            : Operation(name)
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        MallocOperation(
Packit Service 724aca
            OperationName name,
Packit Service 724aca
            unsigned bucketSize)
Packit Service 724aca
            : Operation(name, bucketSize)
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        virtual void perform(const memkind_t &kind,
Packit Service 724aca
                             void *&mem,
Packit Service 724aca
                             size_t size,
Packit Service 724aca
                             size_t offset,
Packit Service 724aca
                             size_t alignment) const override
Packit Service 724aca
        {
Packit Service 724aca
            EMIT(2, "Entering Operation::" << getNameStr()
Packit Service 724aca
                 <<  ", size=" << size
Packit Service 724aca
                 << ", offset=" << offset
Packit Service 724aca
                 << ", alignment=" << alignment
Packit Service 724aca
                 << ", mem=" << mem)
Packit Service 724aca
            switch(m_name) {
Packit Service 724aca
                case Malloc: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    mem = malloc(size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Calloc: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    // split allocation size randomly
Packit Service 724aca
                    // between number of elements and element size
Packit Service 724aca
                    mem = calloc((1 << offset), (size >> offset));
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Realloc: {
Packit Service 724aca
                    mem = realloc(mem, size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Align: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    // randomly choose alignment from (8, 8 * MemalignMaxMultiplie)
Packit Service 724aca
                    mem = memalign(alignment, size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Free: {
Packit Service 724aca
                    free(mem);
Packit Service 724aca
                    mem = nullptr;
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
Packit Service 724aca
                default:
Packit Service 724aca
                    throw "Not implemented";
Packit Service 724aca
                    break;
Packit Service 724aca
            }
Packit Service 724aca
            EMIT(2, "Exiting Operation::" << getNameStr()
Packit Service 724aca
                 <<  ", size=" << size
Packit Service 724aca
                 << ", offset=" << offset
Packit Service 724aca
                 << ", alignment=" << alignment
Packit Service 724aca
                 << ", mem=" << mem)
Packit Service 724aca
        }
Packit Service 724aca
    };
Packit Service 724aca
Packit Service 724aca
#ifdef SYSTEM_JEMALLOC_PREFIX
Packit Service 724aca
    // Jemalloc memory operations
Packit Service 724aca
    class JemallocOperation : public Operation
Packit Service 724aca
    {
Packit Service 724aca
    public:
Packit Service 724aca
        JemallocOperation(
Packit Service 724aca
            OperationName name)
Packit Service 724aca
            : Operation(name)
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        JemallocOperation(
Packit Service 724aca
            OperationName name,
Packit Service 724aca
            unsigned bucketSize)
Packit Service 724aca
            : Operation(name, bucketSize)
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        virtual void perform(const memkind_t &kind,
Packit Service 724aca
                             void *&mem,
Packit Service 724aca
                             size_t size,
Packit Service 724aca
                             size_t offset,
Packit Service 724aca
                             size_t alignment) const override
Packit Service 724aca
        {
Packit Service 724aca
            EMIT(2, "Entering Operation::" << getNameStr()
Packit Service 724aca
                 <<  ", size=" << size
Packit Service 724aca
                 << ", offset=" << offset
Packit Service 724aca
                 << ", alignment=" << alignment
Packit Service 724aca
                 << ", mem=" << mem)
Packit Service 724aca
            switch(m_name) {
Packit Service 724aca
                case Malloc: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        jexx_free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    mem = jexx_malloc(size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Calloc: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        jexx_free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    // split allocation size randomly
Packit Service 724aca
                    // between number of elements and element size
Packit Service 724aca
                    mem = jexx_calloc((1 <<, offset), (size >>, offset));
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Realloc: {
Packit Service 724aca
                    mem = jexx_realloc(mem, size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Align: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        jexx_free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    // randomly choose alignment from (8, 8 * MemalignMaxMultiplie)
Packit Service 724aca
                    mem = jexx_memalign(alignment, size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Free: {
Packit Service 724aca
                    jexx_free(mem);
Packit Service 724aca
                    mem = nullptr;
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
Packit Service 724aca
                default:
Packit Service 724aca
                    throw "Not implemented";
Packit Service 724aca
                    break;
Packit Service 724aca
            }
Packit Service 724aca
            EMIT(2, "Exiting Operation::" << getNameStr()
Packit Service 724aca
                 <<  ", size=" << size
Packit Service 724aca
                 << ", offset=" << offset
Packit Service 724aca
                 << ", alignment=" << alignment
Packit Service 724aca
                 << ", mem=" << mem)
Packit Service 724aca
        }
Packit Service 724aca
    };
Packit Service 724aca
#endif
Packit Service 724aca
    // Jemkmalloc memory operations
Packit Service 724aca
    class JemkmallocOperation : public Operation
Packit Service 724aca
    {
Packit Service 724aca
    public:
Packit Service 724aca
        JemkmallocOperation(
Packit Service 724aca
            OperationName name)
Packit Service 724aca
            : Operation(name)
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        JemkmallocOperation(
Packit Service 724aca
            OperationName name,
Packit Service 724aca
            unsigned bucketSize)
Packit Service 724aca
            : Operation(name, bucketSize)
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        virtual void perform(const memkind_t &kind,
Packit Service 724aca
                             void *&mem,
Packit Service 724aca
                             size_t size,
Packit Service 724aca
                             size_t offset,
Packit Service 724aca
                             size_t alignment) const override
Packit Service 724aca
        {
Packit Service 724aca
#ifdef JEMK
Packit Service 724aca
            EMIT(2, "Entering Operation::" << getNameStr()
Packit Service 724aca
                 <<  ", size=" << size
Packit Service 724aca
                 << ", offset=" << offset
Packit Service 724aca
                 << ", alignment=" << alignment
Packit Service 724aca
                 << ", mem=" << mem)
Packit Service 724aca
            switch(m_name) {
Packit Service 724aca
                case Malloc: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        jemk_free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    mem = jemk_malloc(size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Calloc: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        jemk_free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    // split allocation size randomly
Packit Service 724aca
                    // between number of elements and element size
Packit Service 724aca
                    mem = jemk_calloc((1 << offset), (size >> offset));
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Realloc: {
Packit Service 724aca
                    mem = jemk_realloc(mem, size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Align: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        jemk_free(mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    // randomly choose alignment from (8, 8 * MemalignMaxMultiplie)
Packit Service 724aca
                    mem = jemk_memalign(alignment, size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Free: {
Packit Service 724aca
                    jemk_free(mem);
Packit Service 724aca
                    mem = nullptr;
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
Packit Service 724aca
                default:
Packit Service 724aca
                    throw "Not implemented";
Packit Service 724aca
                    break;
Packit Service 724aca
            }
Packit Service 724aca
            EMIT(2, "Exiting Operation::" << getNameStr()
Packit Service 724aca
                 <<  ", size=" << size
Packit Service 724aca
                 << ", offset=" << offset
Packit Service 724aca
                 << ", alignment=" << alignment
Packit Service 724aca
                 << ", mem=" << mem)
Packit Service 724aca
#endif // JE_MK
Packit Service 724aca
        }
Packit Service 724aca
    };
Packit Service 724aca
Packit Service 724aca
    // Memkind memory operations
Packit Service 724aca
    class MemkindOperation : public Operation
Packit Service 724aca
    {
Packit Service 724aca
    public:
Packit Service 724aca
        MemkindOperation()
Packit Service 724aca
        {}
Packit Service 724aca
Packit Service 724aca
        MemkindOperation(
Packit Service 724aca
            OperationName name)
Packit Service 724aca
            : Operation(name)
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        MemkindOperation(
Packit Service 724aca
            OperationName name,
Packit Service 724aca
            size_t bucketSize)
Packit Service 724aca
            : Operation(name, bucketSize)
Packit Service 724aca
        {
Packit Service 724aca
        }
Packit Service 724aca
Packit Service 724aca
        virtual void perform(const memkind_t &kind,
Packit Service 724aca
                             void *&mem,
Packit Service 724aca
                             size_t size,
Packit Service 724aca
                             size_t offset,
Packit Service 724aca
                             size_t alignment) const override
Packit Service 724aca
        {
Packit Service 724aca
            EMIT(2, "Entering Operation::" << getNameStr()
Packit Service 724aca
                 <<  ", size=" << size
Packit Service 724aca
                 << ", offset=" << offset
Packit Service 724aca
                 << ", alignment=" << alignment
Packit Service 724aca
                 << ", mem=" << mem)
Packit Service 724aca
            switch (m_name) {
Packit Service 724aca
                case Malloc: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        memkind_free(kind, mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    mem = memkind_malloc(kind, size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Calloc: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        memkind_free(kind, mem);
Packit Service 724aca
                    }
Packit Service 724aca
                    // split allocation size randomly
Packit Service 724aca
                    // between number of elements and element size
Packit Service 724aca
                    mem = memkind_calloc(kind, 1 << offset, size >> offset);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Realloc: {
Packit Service 724aca
                    mem = memkind_realloc(kind, mem, size);
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
Packit Service 724aca
                case Align: {
Packit Service 724aca
                    if (mem != nullptr) {
Packit Service 724aca
                        memkind_free(kind, mem);
Packit Service 724aca
                        mem = nullptr;
Packit Service 724aca
                    }
Packit Service 724aca
                    // randomly choose alignment from (sizeof(void*), sizeof(void*) * MemalignMaxMultiplie)
Packit Service 724aca
                    if (memkind_posix_memalign(kind, &mem, alignment, size) != 0) {
Packit Service 724aca
                        // failure
Packit Service 724aca
                        mem = nullptr;
Packit Service 724aca
                    }
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
                case Free: {
Packit Service 724aca
                    memkind_free(kind, mem);
Packit Service 724aca
                    mem = nullptr;
Packit Service 724aca
                    break;
Packit Service 724aca
                }
Packit Service 724aca
Packit Service 724aca
                default:
Packit Service 724aca
                    break;
Packit Service 724aca
            }
Packit Service 724aca
            EMIT(2, "Exiting Operation::" << getNameStr()
Packit Service 724aca
                 <<  ", size=" << size
Packit Service 724aca
                 << ", offset=" << offset
Packit Service 724aca
                 << ", alignment=" << alignment
Packit Service 724aca
                 << ", mem=" << mem)
Packit Service 724aca
        }
Packit Service 724aca
    };
Packit Service 724aca
}