mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +08:00
add cache for arg_alloc/free, cache for 6.56%
This commit is contained in:
parent
d502f83fca
commit
126a817d49
2
port/linux/.vscode/launch.json
vendored
2
port/linux/.vscode/launch.json
vendored
@ -11,7 +11,7 @@
|
||||
"program": "${workspaceFolder}/build/test/pikascript_test",
|
||||
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
|
||||
"args": [
|
||||
"--gtest_filter=pikaMain.returnNullString"
|
||||
// "--gtest_filter=arg_test.*"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
|
@ -119,6 +119,11 @@ int32_t obj_deinit(PikaObj* self) {
|
||||
pikaVM_runByteCode(self, (uint8_t*)bytes);
|
||||
arg_deinit(del);
|
||||
}
|
||||
extern PikaObj* __pikaMain;
|
||||
void _mem_cache_deinit(void);
|
||||
if (self == __pikaMain) {
|
||||
_mem_cache_deinit();
|
||||
}
|
||||
return obj_deinit_no_del(self);
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,40 @@
|
||||
#include "dataString.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
static PIKA_BOOL _do_arg_cache_push(Arg* self, size_t size) {
|
||||
extern PikaMemInfo pikaMemInfo;
|
||||
if (size != PIKA_ARG_CACHE_SIZE) {
|
||||
return PIKA_FALSE;
|
||||
}
|
||||
if (PIKA_ARG_CACHE_POOL_SIZE <= pikaMemInfo.cache_pool_top) {
|
||||
return PIKA_FALSE;
|
||||
}
|
||||
pikaMemInfo.cache_pool[pikaMemInfo.cache_pool_top++] = (uint8_t*)self;
|
||||
pikaMemInfo.heapUsed -= mem_align(arg_getTotleSize(self));
|
||||
return PIKA_TRUE;
|
||||
}
|
||||
|
||||
static PIKA_BOOL _arg_cache_push(Arg* self) {
|
||||
int size = arg_getSize(self);
|
||||
return _do_arg_cache_push(self, size);
|
||||
return PIKA_FALSE;
|
||||
}
|
||||
|
||||
static Arg* _arg_cache_pop(size_t size) {
|
||||
Arg* self = NULL;
|
||||
extern PikaMemInfo pikaMemInfo;
|
||||
if (!(size == PIKA_ARG_CACHE_SIZE)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!(pikaMemInfo.cache_pool_top > 0)) {
|
||||
return NULL;
|
||||
}
|
||||
--pikaMemInfo.cache_pool_top;
|
||||
self = (Arg*)pikaMemInfo.cache_pool[pikaMemInfo.cache_pool_top];
|
||||
pikaMemInfo.heapUsed += mem_align(arg_getTotleSize(self));
|
||||
return self;
|
||||
}
|
||||
|
||||
uint32_t arg_getTotleSize(Arg* self) {
|
||||
return arg_totleSize(self);
|
||||
}
|
||||
@ -55,8 +89,21 @@ static Arg* _arg_set_hash(Arg* self,
|
||||
Arg* next) {
|
||||
/* create arg if not exist */
|
||||
if (NULL == self || self->size < size) {
|
||||
self = (Arg*)pikaMalloc(sizeof(Arg) + size);
|
||||
self->size = size;
|
||||
self = _arg_cache_pop(size);
|
||||
if (PIKA_ASSERT_ENABLE) {
|
||||
extern PikaMemInfo pikaMemInfo;
|
||||
pikaMemInfo.alloc_times++;
|
||||
pikaMemInfo.alloc_times_cache++;
|
||||
}
|
||||
if (NULL == self) {
|
||||
self = (Arg*)pikaMalloc(sizeof(Arg) + size);
|
||||
self->size = size;
|
||||
if (PIKA_ASSERT_ENABLE) {
|
||||
extern PikaMemInfo pikaMemInfo;
|
||||
pikaMemInfo.alloc_times_cache--;
|
||||
}
|
||||
}
|
||||
size = self->size;
|
||||
self->flag = 0;
|
||||
arg_setSerialized(self, PIKA_TRUE);
|
||||
// arg_setIsKeyword(self, PIKA_FALSE);
|
||||
@ -111,6 +158,9 @@ uint32_t arg_totleSize(Arg* self) {
|
||||
void arg_freeContent(Arg* self) {
|
||||
if (NULL != self) {
|
||||
uint32_t totleSize = arg_totleSize(self);
|
||||
if (_arg_cache_push(self)) {
|
||||
return;
|
||||
}
|
||||
pikaFree(self, totleSize);
|
||||
return;
|
||||
}
|
||||
@ -308,7 +358,6 @@ char* arg_getStr(Arg* self) {
|
||||
return (char*)arg_getContent(self);
|
||||
}
|
||||
|
||||
|
||||
uint32_t arg_getContentSize(Arg* self) {
|
||||
return arg_getSize(self);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ void* pikaMalloc(uint32_t size) {
|
||||
//! if you unsure about the __impl_pikaMalloc, uncomment this to force alignment
|
||||
#if PIKA_ARG_ALIGN_ENABLE
|
||||
/* force alignment to avoid unaligned access */
|
||||
size = (size + 4 - 1) & ~(4 - 1);
|
||||
size = mem_align(size);
|
||||
#endif
|
||||
|
||||
pikaMemInfo.heapUsed += size;
|
||||
@ -51,8 +51,7 @@ void* pikaMalloc(uint32_t size) {
|
||||
void* mem = __user_malloc(size);
|
||||
__platform_enable_irq_handle();
|
||||
if (NULL == mem) {
|
||||
__platform_printf(
|
||||
"Error: No heap space! Please reset the device.\r\n");
|
||||
__platform_printf("Error: No heap space! Please reset the device.\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@ -67,7 +66,7 @@ void pikaFree(void* mem, uint32_t size) {
|
||||
//! if you unsure about the __impl_pikaMalloc, uncomment this to force alignment
|
||||
#if PIKA_ARG_ALIGN_ENABLE
|
||||
/* force alignment to avoid unaligned access */
|
||||
size = (size + 4 - 1) & ~(4 - 1);
|
||||
size = mem_align(size);
|
||||
#endif
|
||||
|
||||
__platform_disable_irq_handle();
|
||||
@ -245,7 +244,6 @@ void pool_free(Pool* pool, void* mem, uint32_t size) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BitMap bitmap_init(uint32_t size) {
|
||||
BitMap mem_bit_map =
|
||||
(BitMap)__platform_malloc(((size - 1) / 8 + 1) * sizeof(char));
|
||||
@ -309,7 +307,15 @@ void mem_pool_init(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void _mem_cache_deinit(void) {
|
||||
while (pikaMemInfo.cache_pool_top) {
|
||||
__platform_free(pikaMemInfo.cache_pool[pikaMemInfo.cache_pool_top - 1]);
|
||||
pikaMemInfo.cache_pool_top--;
|
||||
}
|
||||
}
|
||||
|
||||
void mem_pool_deinit(void) {
|
||||
_mem_cache_deinit();
|
||||
#if PIKA_POOL_ENABLE
|
||||
pool_deinit(&pikaPool);
|
||||
#endif
|
||||
|
@ -41,6 +41,10 @@
|
||||
typedef struct {
|
||||
uint32_t heapUsed;
|
||||
uint32_t heapUsedMax;
|
||||
uint8_t* cache_pool[PIKA_ARG_CACHE_POOL_SIZE];
|
||||
uint32_t cache_pool_top;
|
||||
uint32_t alloc_times;
|
||||
uint32_t alloc_times_cache;
|
||||
} PikaMemInfo;
|
||||
|
||||
typedef uint8_t* BitMap;
|
||||
@ -78,5 +82,7 @@ void bitmap_deinit(BitMap bitmap);
|
||||
void mem_pool_deinit(void);
|
||||
void mem_pool_init(void);
|
||||
|
||||
#define mem_align(_size) ((((_size) + 4 - 1) & ~(4 - 1)))
|
||||
|
||||
#undef __DATA_MEMORY_CLASS_IMPLEMENT__
|
||||
#endif
|
||||
|
@ -309,6 +309,14 @@
|
||||
#define PIKA_FLOAT_TYPE_DOUBLE 1
|
||||
#endif
|
||||
|
||||
#ifndef PIKA_ARG_CACHE_POOL_SIZE
|
||||
#define PIKA_ARG_CACHE_POOL_SIZE 32
|
||||
#endif
|
||||
|
||||
#ifndef PIKA_ARG_CACHE_SIZE
|
||||
#define PIKA_ARG_CACHE_SIZE 8
|
||||
#endif
|
||||
|
||||
/* configuration validation */
|
||||
|
||||
#endif
|
||||
|
@ -1837,57 +1837,56 @@ TEST(vm, getattr) {
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
// TEST(vm, setattr) {
|
||||
// /* init */
|
||||
// pikaMemInfo.heapUsedMax = 0;
|
||||
// PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||
// extern unsigned char pikaModules_py_a[];
|
||||
// obj_linkLibrary(pikaMain, pikaModules_py_a);
|
||||
// /* run */
|
||||
// __platform_printf("BEGIN\r\n");
|
||||
// obj_run(pikaMain,
|
||||
// "class test:\n"
|
||||
// " a = 1\n"
|
||||
// " def __setattr__(self, name, val):\n"
|
||||
// " print((name, val))\n"
|
||||
// "t = test()\n"
|
||||
// "t.a = 1\n"
|
||||
// "t.b = 'test'\n");
|
||||
// /* collect */
|
||||
// /* assert */
|
||||
// EXPECT_STREQ(log_buff[2], "BEGIN\r\n");
|
||||
// EXPECT_STREQ(log_buff[1], "('a', 1)\r\n");
|
||||
// EXPECT_STREQ(log_buff[0], "('b', 'test')\r\n");
|
||||
// /* deinit */
|
||||
// obj_deinit(pikaMain);
|
||||
// EXPECT_EQ(pikaMemNow(), 0);
|
||||
// }
|
||||
TEST(vm, setattr) {
|
||||
/* init */
|
||||
pikaMemInfo.heapUsedMax = 0;
|
||||
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||
extern unsigned char pikaModules_py_a[];
|
||||
obj_linkLibrary(pikaMain, pikaModules_py_a);
|
||||
/* run */
|
||||
__platform_printf("BEGIN\r\n");
|
||||
obj_run(pikaMain,
|
||||
"class test:\n"
|
||||
" a = 1\n"
|
||||
" def __setattr__(self, name, val):\n"
|
||||
" print((name, val))\n"
|
||||
"t = test()\n"
|
||||
"t.a = 1\n"
|
||||
"t.b = 'test'\n");
|
||||
/* collect */
|
||||
/* assert */
|
||||
EXPECT_STREQ(log_buff[2], "BEGIN\r\n");
|
||||
EXPECT_STREQ(log_buff[1], "('a', 1)\r\n");
|
||||
EXPECT_STREQ(log_buff[0], "('b', 'test')\r\n");
|
||||
/* deinit */
|
||||
obj_deinit(pikaMain);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
// TEST(vm, c_module_get_set_attr) {
|
||||
// /* init */
|
||||
// pikaMemInfo.heapUsedMax = 0;
|
||||
// PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||
// extern unsigned char pikaModules_py_a[];
|
||||
// obj_linkLibrary(pikaMain, pikaModules_py_a);
|
||||
// /* run */
|
||||
// __platform_printf("BEGIN\r\n");
|
||||
// obj_run(pikaMain,
|
||||
// "t = GTestTask.ProxyTest()\n"
|
||||
// "t.a\n"
|
||||
// "t.b\n"
|
||||
// "t.a = 'test1'\n"
|
||||
// "t.b = 'test2'\n");
|
||||
// /* collect */
|
||||
// /* assert */
|
||||
// EXPECT_STREQ(log_buff[3], "'a'\r\n");
|
||||
// EXPECT_STREQ(log_buff[2], "'b'\r\n");
|
||||
// EXPECT_STREQ(log_buff[1], "GTestTask_ProxyTest___setattr__: a,
|
||||
// test1\r\n"); EXPECT_STREQ(log_buff[0], "GTestTask_ProxyTest___setattr__:
|
||||
// b, test2\r\n");
|
||||
// /* deinit */
|
||||
// obj_deinit(pikaMain);
|
||||
// EXPECT_EQ(pikaMemNow(), 0);
|
||||
// }
|
||||
TEST(vm, c_module_get_set_attr) {
|
||||
/* init */
|
||||
pikaMemInfo.heapUsedMax = 0;
|
||||
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||
extern unsigned char pikaModules_py_a[];
|
||||
obj_linkLibrary(pikaMain, pikaModules_py_a);
|
||||
/* run */
|
||||
__platform_printf("BEGIN\r\n");
|
||||
obj_run(pikaMain,
|
||||
"t = GTestTask.ProxyTest()\n"
|
||||
"t.a\n"
|
||||
"t.b\n"
|
||||
"t.a = 'test1'\n"
|
||||
"t.b = 'test2'\n");
|
||||
/* collect */
|
||||
/* assert */
|
||||
EXPECT_STREQ(log_buff[3], "'a'\r\n");
|
||||
EXPECT_STREQ(log_buff[2], "'b'\r\n");
|
||||
EXPECT_STREQ(log_buff[1], "GTestTask_ProxyTest___setattr__: a, test1\r\n");
|
||||
EXPECT_STREQ(log_buff[0], "GTestTask_ProxyTest___setattr__: b, test2\r\n");
|
||||
/* deinit */
|
||||
obj_deinit(pikaMain);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(vm, class_attr_ref) {
|
||||
/* init */
|
||||
|
@ -1,5 +1,15 @@
|
||||
#include "test_common.h"
|
||||
|
||||
TEST(arg_test, cache_){
|
||||
Arg* arg1 = arg_newInt(1);
|
||||
arg_deinit(arg1);
|
||||
Arg* arg2 = arg_newInt(2);
|
||||
int val = arg_getInt(arg2);
|
||||
EXPECT_EQ(val, 2);
|
||||
arg_deinit(arg2);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(arg_test, int_) {
|
||||
Arg* arg = New_arg(NULL);
|
||||
arg = arg_setInt(arg, "test", 1);
|
||||
@ -64,11 +74,11 @@ TEST(arg_test, null) {
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
Arg* arg_strAppend(Arg* arg_in, char* str_to_append);
|
||||
TEST(arg_test, append) {
|
||||
Arg* arg = arg_newStr("test");
|
||||
arg = arg_append(arg, (void*)"hello", sizeof("hello"));
|
||||
EXPECT_STREQ(arg_getStr(arg), "test");
|
||||
EXPECT_STREQ(arg_getStr(arg) + sizeof("test"), "hello");
|
||||
arg = arg_strAppend(arg, "hello");
|
||||
EXPECT_STREQ(arg_getStr(arg), "testhello");
|
||||
arg_deinit(arg);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
@ -10,5 +10,13 @@ int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int res = RUN_ALL_TESTS();
|
||||
mem_pool_deinit();
|
||||
extern PikaMemInfo pikaMemInfo;
|
||||
if (PIKA_ASSERT_ENABLE) {
|
||||
printf("[ Info]: alloc times: %d, cached times: %d (%0.2f%%)\r\n",
|
||||
pikaMemInfo.alloc_times, pikaMemInfo.alloc_times_cache,
|
||||
((float)pikaMemInfo.alloc_times_cache /
|
||||
(float)pikaMemInfo.alloc_times) *
|
||||
100.0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user