Ясно, что не существует явного способа или определенных системных вызовов, которые помочь программистам поместить переменную в кэш ЦП.
Но я думаю, что определенный стиль программирования или хорошо продуманный алгоритм может позволить увеличить возможности того, что переменную можно кэшировать в кэш ЦП.
Вот мой пример:
Я хочу добавить 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);
}