Commit 5d815fa5 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Remove unused kis_memory_pool

parent 0d7a03ef
/*
* Copyright (c) 2010 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __KIS_MEMORY_POOL_H
#define __KIS_MEMORY_POOL_H
#include "stdlib.h"
//#define DEBUG_HIT_MISS
#ifdef DEBUG_HIT_MISS
#include "kis_debug.h"
#define DECLARE_STATUS_VAR() qint64 m_hit; qint64 m_miss; qint64 m_averIndex; qint32 m_maxIndex
#define INIT_STATUS_VAR() m_hit=0; m_miss=0; m_averIndex=0; m_maxIndex=0
#define POOL_MISS() m_miss++
#define POOL_HIT(idx) m_hit++; m_averIndex+=idx; m_maxIndex=qMax(m_maxIndex, idx)
#define REPORT_STATUS() dbgKrita << ppVar(m_hit) << ppVar(m_miss) << "Hit rate:" << double(m_hit)/(m_hit+m_miss) << "Max index:" << m_maxIndex <<"Av. index:" << double(m_averIndex)/(m_hit)
#else
#define DECLARE_STATUS_VAR()
#define INIT_STATUS_VAR()
#define POOL_MISS()
#define POOL_HIT(idx)
#define REPORT_STATUS()
#endif
/**
* Memory pool object for fast allocation of big objects.
* Please, don't even try to use it for small objects -
* it's pointless. glibc will be faster anyway.
*
* What is small and what is big object? On my machine
* (2GiB of RAM) glibc's memory pool seemed to be about
* 128-256KiB. So if the total size of constantly
* allocated/deallocated objects grows higher 128KiB,
* you need to use this pool.
*
* In tests, there is no big difference between pools of
* size 32 and of size 64.
*
* How does it work? Very simple. The pool has an array
* of atomic pointers to memory chunks. When memory request
* comes, it searches in the array for the first non-zero
* pointer and rerurns it. When the pointer is returned back -
* the pool writes it to the first free slot.
*/
template<class T, int SIZE>
class KisMemoryPool
{
public:
KisMemoryPool() {
INIT_STATUS_VAR();
}
~KisMemoryPool() {
for(qint32 i = 0; i < SIZE; i++) {
free(m_array[i]);
}
REPORT_STATUS();
}
inline void push(void *ptr) {
if(m_allocated < SIZE) {
for(qint32 i = 0; i < SIZE; i++) {
if(m_array[i].testAndSetOrdered(0, ptr)) {
m_allocated.ref();
return;
}
}
}
free(ptr);
}
inline void* pop() {
if(m_allocated > 0) {
void *ptr;
for(qint32 i = 0; i < SIZE; i++) {
ptr = m_array[i].fetchAndStoreOrdered(0);
if (ptr) {
m_allocated.deref();
POOL_HIT(i);
return ptr;
}
}
}
POOL_MISS();
return malloc(sizeof(T));
}
private:
QAtomicPointer<void> m_array[SIZE];
QAtomicInt m_allocated;
DECLARE_STATUS_VAR()
};
#define POOL_OPERATORS(T) \
void* operator new(size_t size) { \
return size == sizeof(T) ? __m_pool.pop() : malloc(size); \
} \
void operator delete(void *ptr, size_t size) { \
if(size == sizeof(T)) __m_pool.push(ptr); \
else free(ptr); \
}
#define DECLARE_POOL(T,SIZE) \
static KisMemoryPool<T,SIZE> __m_pool
#define DEFINE_POOL(T,SIZE) \
KisMemoryPool<T,SIZE> T::__m_pool
#endif /* __KIS_MEMORY_POOL_H */
......@@ -19,23 +19,6 @@ ecm_add_tests(
set_tests_properties(krita-image-tiles3-kis_low_memory_tests PROPERTIES TIMEOUT 180)
########### next target ###############
#kisdoc
#set(kis_tile_compressors_test_SRCS kis_tile_compressors_test.cpp )
#kde4_add_unit_test(KisTileCompressorsTest TEST_NAME krita-image-KisTileCompressorsTest ${kis_tile_compressors_test_SRCS})
#target_LINK_LIBRARIES(KisTileCompressorsTest kritaodf kritaimage Qt5::Test)
########### next target ###############
#kisdoc
#set(kis_compression_tests_SRCS kis_compression_tests.cpp )
#kde4_add_unit_test(KisCompressionTests TEST_NAME krita-image-KisCompressionTests ${kis_compression_tests_SRCS})
#target_LINK_LIBRARIES(KisCompressionTests kritaimage Qt5::Test)
ecm_add_test(
kis_memory_pool_test.cpp
TEST_NAME krita-image-KisMemoryPoolTest
LINK_LIBRARIES kritaglobal Qt5::Test)
ecm_add_test(
kis_chunk_allocator_test.cpp ../swap/kis_chunk_allocator.cpp
TEST_NAME krita-image-KisChunkAllocatorTest
......
/*
* Copyright (c) 2010 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_memory_pool_test.h"
#include <QTest>
#include "kis_debug.h"
#include "../kis_memory_pool.h"
#define OBJECT_SIZE 16384 //bytes (size of a usual tile data)
#define POOL_SIZE 32
#define NUM_THREADS 2
#define NUM_CYCLES 100000
#define NUM_OBJECTS 64 // for tiles - 64 == area of 512x512px
class TestingClass
{
public:
quint8 m_data[OBJECT_SIZE];
};
typedef KisMemoryPool<TestingClass, POOL_SIZE> TestingMemoryPool;
class KisPoolStressJob : public QRunnable
{
public:
KisPoolStressJob(TestingMemoryPool &pool)
: m_pool(pool)
{
}
void run() override {
qsrand(QTime::currentTime().msec());
for(qint32 i = 0; i < NUM_CYCLES; i++) {
qint32 type = i % 2;
switch(type) {
case 0:
for(qint32 j = 0; j < NUM_OBJECTS; j++) {
m_pointer[j] = m_pool.pop();
Q_ASSERT(m_pointer[j]);
// check for sigsegv ;)
((quint8*)m_pointer[j])[0] = i;
}
break;
case 1:
for(qint32 j = 0; j < NUM_OBJECTS; j++) {
// are we the only writers here?
Q_ASSERT(((quint8*)m_pointer[j])[0] == (i-1) % 256);
m_pool.push(m_pointer[j]);
}
break;
}
}
}
private:
void* m_pointer[NUM_OBJECTS];
TestingMemoryPool &m_pool;
};
void KisMemoryPoolTest::benchmarkMemoryPool()
{
TestingMemoryPool memoryPool;
QThreadPool pool;
pool.setMaxThreadCount(NUM_THREADS);
QBENCHMARK {
for(qint32 i = 0; i < NUM_THREADS; i++) {
KisPoolStressJob *job = new KisPoolStressJob(memoryPool);
pool.start(job);
}
pool.waitForDone();
}
}
class KisAllocStressJob : public QRunnable
{
public:
KisAllocStressJob()
{
}
void run() override {
qsrand(QTime::currentTime().msec());
for(qint32 i = 0; i < NUM_CYCLES; i++) {
qint32 type = i % 2;
switch(type) {
case 0:
for(qint32 j = 0; j < NUM_OBJECTS; j++) {
m_pointer[j] = new TestingClass;
Q_ASSERT(m_pointer[j]);
// check for sigsegv ;)
((quint8*)m_pointer[j])[0] = i;
}
break;
case 1:
for(qint32 j = 0; j < NUM_OBJECTS; j++) {
// are we the only writers here?
Q_ASSERT(((quint8*)m_pointer[j])[0] == (i-1) % 256);
delete (TestingClass*)m_pointer[j];
}
break;
}
}
}
private:
void* m_pointer[NUM_OBJECTS];
};
void KisMemoryPoolTest::benchmarkAlloc()
{
QThreadPool pool;
pool.setMaxThreadCount(NUM_THREADS);
QBENCHMARK {
for(qint32 i = 0; i < NUM_THREADS; i++) {
KisAllocStressJob *job = new KisAllocStressJob();
pool.start(job);
}
pool.waitForDone();
}
}
QTEST_MAIN(KisMemoryPoolTest)
/*
* Copyright (c) 2010 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_MEMORY_POOL_TEST_H
#define KIS_MEMORY_POOL_TEST_H
#include <QtTest>
class KisMemoryPoolTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void benchmarkMemoryPool();
void benchmarkAlloc();
};
#endif /* KIS_MEMORY_POOL_TEST_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment