Commit e905bad9816b19fa0004a54d2cda7ba840ca6b93
1 parent
0c2907f9
optimize allocation for GNU systems. That is allocate only blocks of a size malloc handles.
Showing
1 changed file
with
43 additions
and
96 deletions
@@ -623,65 +623,13 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) | @@ -623,65 +623,13 @@ deleteElement(struct memSegment ** tree, struct memSegment * element) | ||
623 | return del_node; | 623 | return del_node; |
624 | } | 624 | } |
625 | 625 | ||
626 | - | ||
627 | -//static | ||
628 | -//void | ||
629 | -//traverse(struct memSegment * tree, void (*cb)(struct memSegment *, int)) | ||
630 | -//{ | ||
631 | -// struct memSegment * previous = tree; | ||
632 | -// struct memSegment * node = tree; | ||
633 | -// int depth = 1; | ||
634 | -// | ||
635 | -// /* | ||
636 | -// * I think this has something like O(n+log(n)) on a ballanced | ||
637 | -// * tree because I have to traverse back the rightmost leaf to | ||
638 | -// * the root to get a break condition. | ||
639 | -// */ | ||
640 | -// while (node) { | ||
641 | -// /* | ||
642 | -// * If we come from the right so nothing and go to our | ||
643 | -// * next parent. | ||
644 | -// */ | ||
645 | -// if (previous == node->right) { | ||
646 | -// previous = node; | ||
647 | -// node = node->parent; | ||
648 | -// depth--; | ||
649 | -// continue; | ||
650 | -// } | ||
651 | -// | ||
652 | -// if ((NULL == node->left || previous == node->left)) { | ||
653 | -// /* | ||
654 | -// * If there are no more elements to the left or we | ||
655 | -// * came from the left, process data. | ||
656 | -// */ | ||
657 | -// cb(node, depth); | ||
658 | -// previous = node; | ||
659 | -// | ||
660 | -// if (NULL != node->right) { | ||
661 | -// node = node->right; | ||
662 | -// depth++; | ||
663 | -// } else { | ||
664 | -// node = node->parent; | ||
665 | -// depth--; | ||
666 | -// } | ||
667 | -// } else { | ||
668 | -// /* | ||
669 | -// * if there are more elements to the left go there. | ||
670 | -// */ | ||
671 | -// previous = node; | ||
672 | -// node = node->left; | ||
673 | -// depth++; | ||
674 | -// } | ||
675 | -// } | ||
676 | -//} | ||
677 | - | ||
678 | static | 626 | static |
679 | void | 627 | void |
680 | post(struct memSegment * tree, void (*cb)(struct memSegment *, int)) | 628 | post(struct memSegment * tree, void (*cb)(struct memSegment *, int)) |
681 | { | 629 | { |
682 | struct memSegment * previous = tree; | 630 | struct memSegment * previous = tree; |
683 | struct memSegment * node = tree; | 631 | struct memSegment * node = tree; |
684 | - int depth = 1; | 632 | + int depth = 1; |
685 | 633 | ||
686 | /* | 634 | /* |
687 | * I think this has something like O(n+log(n)) on a ballanced | 635 | * I think this has something like O(n+log(n)) on a ballanced |
@@ -732,42 +680,6 @@ post(struct memSegment * tree, void (*cb)(struct memSegment *, int)) | @@ -732,42 +680,6 @@ post(struct memSegment * tree, void (*cb)(struct memSegment *, int)) | ||
732 | } | 680 | } |
733 | } | 681 | } |
734 | 682 | ||
735 | -//void | ||
736 | -//printElement(struct memSegment * node, int depth) | ||
737 | -//{ | ||
738 | -// int i; | ||
739 | -// | ||
740 | -// printf("%s %010zu:%p(%02d)", | ||
741 | -// (node->color==rbRed)?"R":"B", | ||
742 | -// node->size, | ||
743 | -// node->ptr, | ||
744 | -// depth); | ||
745 | -// for (i=0; i<depth; i++) printf("-"); | ||
746 | -// puts(""); | ||
747 | -// | ||
748 | -// node = node->next; | ||
749 | -// while (NULL != node) { | ||
750 | -// printf(" %s %010zu:%p(%02d)", | ||
751 | -// (node->color==rbRed)?"R":"B", | ||
752 | -// node->size, | ||
753 | -// node->ptr, | ||
754 | -// depth); | ||
755 | -// for (i=0; i<depth; i++) printf("-"); | ||
756 | -// puts(""); | ||
757 | -// node = node->next; | ||
758 | -// } | ||
759 | -//} | ||
760 | - | ||
761 | -//void | ||
762 | -//cleanup(struct memSegment * node, int depth) | ||
763 | -//{ | ||
764 | -// while (NULL != node) { | ||
765 | -// struct memSegment * next = node->next; | ||
766 | -// free(node); | ||
767 | -// node = next; | ||
768 | -// } | ||
769 | -//} | ||
770 | - | ||
771 | static | 683 | static |
772 | struct memSegment * segments = NULL; | 684 | struct memSegment * segments = NULL; |
773 | 685 | ||
@@ -793,20 +705,55 @@ TR_reference(void * mem) | @@ -793,20 +705,55 @@ TR_reference(void * mem) | ||
793 | } | 705 | } |
794 | 706 | ||
795 | /* | 707 | /* |
796 | - * This will always allocate a multiple of PAGESIZE | 708 | + * This tries to reflect the memory management behaviour of the |
709 | + * GNU version of malloc. For other versions this might need | ||
710 | + * to be changed to be optimal. | ||
711 | + * | ||
712 | + * However, GNU malloc keeps separate pools for each power of | ||
713 | + * 2 memory size up to page size. So one page consists all of | ||
714 | + * memory blocks of the same sizei (a power of 2). | ||
715 | + * | ||
716 | + * Also as far as I understand the smallest allocatable block is | ||
717 | + * 8 bytes. At least the adresses are alwayse a multiple of 8. | ||
718 | + * | ||
719 | + * So lets say page size is 4096. There is nothing allocated | ||
720 | + * right now. We allocate a block of 8 bytes. This will request | ||
721 | + * a memory page from the OS. Then define it as a page containing | ||
722 | + * 8 byte blocks and return the address of the first one of these. | ||
723 | + * Any subsequent call to malloc for 8 bytes will return one of the | ||
724 | + * blocks within this page as long as there are some left. | ||
725 | + * | ||
726 | + * So what we do here is up to page size round the request size up | ||
727 | + * to the next power of 2 >= 8. | ||
728 | + * Sizes greater then pagesize will be round up to the next | ||
729 | + * multiple of pagesize. As far as I understand these are not | ||
730 | + * pooled anyway. | ||
731 | + * | ||
732 | + * For now this assumes we are on a little endian machine. | ||
797 | */ | 733 | */ |
798 | void * | 734 | void * |
799 | TR_malloc(size_t size) | 735 | TR_malloc(size_t size) |
800 | { | 736 | { |
801 | - struct memSegment * seg = NULL; | ||
802 | - //long psize = sysconf(_SC_PAGESIZE); | ||
803 | - long psize = 64; | 737 | + struct memSegment * seg = NULL; |
738 | + long psize = sysconf(_SC_PAGESIZE); | ||
739 | + size_t check; | ||
804 | 740 | ||
805 | size += sizeof(struct memSegment); | 741 | size += sizeof(struct memSegment); |
806 | 742 | ||
807 | - /* allocate only blocks of a multiple of pagesize, similar to cbuf */ | ||
808 | - size = (0>=size)?1:(0!=size%psize)?(size/psize)+1:size/psize; | ||
809 | - size *= psize; | 743 | + if (size > psize) { |
744 | + if (0 != (size % psize)) { | ||
745 | + // size if not a multiple of pagesize so bring it to one. | ||
746 | + size = ((size / psize) + 1) * psize; | ||
747 | + } | ||
748 | + } else { | ||
749 | + check = size >> 1; | ||
750 | + check = (size | check) - check; | ||
751 | + | ||
752 | + if (check != size) { | ||
753 | + // size is not a power of 2 so bring it to one. | ||
754 | + size = ((size << 1) | size) - size; | ||
755 | + } | ||
756 | + } | ||
810 | 757 | ||
811 | #ifdef MEM_OPT | 758 | #ifdef MEM_OPT |
812 | seg = findElement(segments, size); | 759 | seg = findElement(segments, size); |
Please
register
or
login
to post a comment