Алгоритм распределения друзей - расширение кучи

0

Это второй запрос к моей реализации схемы распределения друзей, первый вопрос здесь, который также объясняет, что такое распределение Бадди. В стандартной реализации один начинается с большого блока 2 ^ i, где я - целое число, которое работает со статическим размером кучи (вся куча - это самый большой блок в этом случае).

Мой вопрос зависит от реализации, которая имеет дело с динамически размерной кучей, где размер кучи начинается с 0. В настоящее время, когда самый высокий порядок i, не может найти блок в свободном списке (список свободных блоков), я делаю звонок чтобы увеличить размер кучи, чтобы соответствовать этому блоку высшего порядка.

Проблема в том, что я не уверен, что эта производная нарушает инвариант в системе buddy, который является вычислением адреса блока приятелей, заданного адресом. Это просто можно вычислить, перевернув бит i-го порядка. Объяснение этого расчета в моем предыдущем вопросе. Когда я реализую эту схему, иногда я возвращаю неправильный адрес друга.

  • 0
    Какой вызов вы делаете, чтобы увеличить размер кучи?
  • 0
    @fvdalcin Это пользовательский вызов, все, что он делает, это перемещает указатель на заднюю часть кучи дальше назад с помощью аргумента размера и возвращает пустой указатель на первый адрес в этом новом выделенном блоке.
Показать ещё 2 комментария
Теги:
algorithm
memory
memory-management

2 ответа

1
Лучший ответ

Я не совсем уверен, если вы можете увеличить размер кучи после того, как некоторые блоки уже выделены. Я думаю, вам придется увеличить свою кучу и перераспределить все блоки снова, следуя алгоритму распределения, но теперь рассматривая ваш новый размер кучи.

1
    #include <stdio.h>

typedef struct X 
{
    unsigned int address;
    int empty;
    int id_req;//id_req
    int allow;
} Block;

typedef struct Y  
{
    int enz;
    int id_req;//req_id
    int ok;
} Defer;

unsigned int block_sizes[8] = {0};
unsigned int memSize;
unsigned int allcSize;

Block blocks[8][128];
int num_blocks[8];

int defer_pointer = 0;
Defer defers[100];

int main(int argc, char **argv)
{
    int x, y, z; 

    for(x = 0;x < 100;x++)
        defers[x].ok = 1;

    for(x = 0;x < 8;x++)
        for(y = 0;y < 128;y++)
            blocks[x][y].empty = blocks[x][y].allow = 0;

    scanf("%u", &memSize);
    scanf("%u", &allcSize);

    block_sizes[0] = allcSize;
    for(x = 0;x+1 < 8;x++)
        if(block_sizes[x] == memSize)
            break;
        else
            block_sizes[x+1] = block_sizes[x]*2;

    blocks[x][0].address = 0;
    blocks[x][0].empty = 1;
    num_blocks[x] = 1;
    for(;x > 0;x--)
    {
        num_blocks[x-1] = num_blocks[x]*2;

        for(y=0;y < num_blocks[x];y++)
        {
            blocks[x-1][2*y].address = blocks[x][y].address;
            blocks[x-1][2*y+1].address = blocks[x][y].address + block_sizes[x-1];
        }
    }

    while(scanf("%d", &z) != EOF)
    {
        char op = getchar();
        while(op != '-' && op != '+') op = getchar();

        if(op == '+')
        {
            unsigned int size;
            scanf("%u", &size);
            printf("Request ID %d: allocates %u byte%s.\n", z, size, size == 1 ? "" : "s");

            int enz = 0;
            while(block_sizes[enz] < size)
                enz++;

            unsigned int address;
            if(allocate(enz, z, &address)) 
            {
                printf("\tSuccess; addr = 0x%08x.\n", address);
            }
            else
            {
                printf("\tRequest deferred.\n");
                defers[defer_pointer].ok = 0;
                defers[defer_pointer].enz = enz;
                defers[defer_pointer].id_req = z;
                defer_pointer++;
            }
        }
        else
        {
            printf("Request ID %d: deallocate.\n", z);

            int success = 0;
            for(x = 0;x < 8 && block_sizes[x] != 0 && success != 1;x++)
                for(y = 0;y < num_blocks[x] && success != 1;y++)
                    if(blocks[x][y].allow)

                        if (blocks[x][y].id_req == z)
                        {
                            blocks[x][y].allow = 0;
                            blocks[x][y].empty = 1;
                            success = 1;
                        }

            x--;y--;

            if(success)
                printf("\tSuccess.\n");
            else
                continue;
            // the buddy system

            while(x < 8 && num_blocks[x] > 1)
            {
                int buddy = (blocks[x][y].address / block_sizes[x]) %2 == 0 ? (y+1) : (y-    1);

                if(blocks[x][buddy].empty)
                {
                    blocks[x][y].empty = 0;
                    blocks[x][buddy].empty = 0;

                    blocks[x+1][y/2].empty = 1;
                    x++;
                    y /= 2;
                }
                else
                {
                    break;
                }
            }

            for(x = 0;x < defer_pointer;x++)
                if(!defers[x].ok)
                {
                    unsigned int address;
                    if(allocate(defers[x].enz, defers[x].id_req, &address))
                    {
                        defers[x].ok = 1;
                        printf("\tDeferred request %d allocated; addr = 0x%08x\n", defers[x].id_req, address);
                    }
                }
        }
    }

    return 0;
}

int allocate(int enz, int id_req, unsigned int *address)
{
    int x, y, ret = 0;
    for(x = enz;x < 8 && block_sizes[x] != 0 && ret == 0;x++)
        for(y = 0;y < num_blocks[x] && ret == 0;y++)
            if(blocks[x][y].empty)
                ret = 1;
    x--;y--;
    if(ret == 0)
        return 0;

    while(x != enz)
    {
        blocks[x][y].empty = 0;

        blocks[x-1][2*y].empty = 1;
        blocks[x-1][2*y+1].empty = 1;

        x = x-1;
        y = 2*y;
    }

    blocks[x][y].empty = 0;
    blocks[x][y].id_req = id_req;
    blocks[x][y].allow = 1;
    *address = blocks[x][y].address;
}
  • 0
    Вышеприведенная программа показывает базовую реализацию системы друзей, в которой показано расширение кучи при распределении друзей.
  • 0
    Надеюсь, это может помочь кому-то

Ещё вопросы

Сообщество Overcoder
Наверх
Меню