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