Как поместить мою структурную переменную в CPU кеши для сокращения времени доступа к странице основной памяти? Параметры

Ясно, что не существует явного способа или определенных системных вызовов, которые помочь программистам поместить переменную в кэш ЦП.

Но я думаю, что определенный стиль программирования или хорошо продуманный алгоритм может позволить увеличить возможности того, что переменную можно кэшировать в кэш ЦП.

Вот мой пример:

Я хочу добавить 8-байтовую структуру в конец массива, состоящего однотипных структур, объявленных в глобальной основной памяти регион.

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

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

Я думаю, что некоторые хитрые коды могут сократить затраченное время до 10–100 раз. Пожалуйста, покажите мне путь.

-------------------------------------------------------------------------

Добавлен (2011-04-01)

Дэймон ~ спасибо за ваш комментарий!

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

Чтобы точно измерить время выполнения каждой операции (в исходном коде есть несколько различных типов операций), я вставил код измерения времени, используя clock_gettime () функция. Я думал, что если я буду измерять время выполнения каждой операции и накапливать их, можно избежать дополнительных затрат на основной цикл.

В исходном коде код измерения времени был скрыт макрос-функцией, поэтому я полностью забыл об этом.

Время работы этого кода составляет почти 6 секунд. Но если я избавлюсь от функции измерения времени в основном цикле, она станет 0,1 секунды.

Поскольку функция clock_gettime () поддерживает очень высокую точность (до 1 наносекунды), Я думаю, что эта функция вызвала кэширование основной области памяти, в которой выполняются последовательные вставки.

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

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


typedef struct t_ptr {
    uint32 isleaf :1, isNextLeaf :1, ptr :30;
    t_ptr(void) {
        isleaf = false;
        isNextLeaf = false;
        ptr = NIL;
    }
} PTR;

typedef struct t_key {
    uint32 op :1, key :31;
    t_key(void) {
        op = OP_INS;
        key = 0;
    }
} KEY;

typedef struct t_key_pair {
    KEY key;
    PTR ptr;
    t_key_pair() {
    }

    t_key_pair(KEY k, PTR p) {
        key = k;
        ptr = p;
    }
} KeyPair;

typedef struct t_op {
    KeyPair keyPair;
    uint seq;
    t_op() {
        seq = 0;
    }
} OP;

#define MAX_OP_LEN 4000000
typedef struct t_opq {
    OP ops[MAX_OP_LEN];
    int freeOffset;
    int globalSeq;
    bool queueOp(register KeyPair keyPair);
} OpQueue;

bool OpQueue::queueOp(register KeyPair keyPair) {
    bool isFull = false;
    if (freeOffset == (int) (MAX_OP_LEN - 1)) {
        isFull = true;
    }
    ops[freeOffset].keyPair = keyPair;
    ops[freeOffset].seq = globalSeq++;
    freeOffset++;
}

OpQueue opQueue;
#include 
int main() {
    struct timespec startTime, endTime, totalTime;
    for(int i = 0; i < 4000000; i++) {
        clock_gettime(CLOCK_REALTIME, &startTime);
        opQueue.queueOp(KeyPair());
        clock_gettime(CLOCK_REALTIME, &endTime);
        totalTime.tv_sec += (endTime.tv_sec - startTime.tv_sec);
        totalTime.tv_nsec += (endTime.tv_nsec - startTime.tv_nsec);
    }
    printf("\n elapsed time: %ld", totalTime.tv_sec * 1000000LL + totalTime.tv_nsec / 1000L);
}

8
задан Peter Mortensen 26 June 2012 в 19:38
поделиться