Я работаю над домашним заданием, где я должен вручную оптимизировать вложенный цикл (моя программа будет скомпилирована с отключенной оптимизацией).Цель задания - запустить всю программу менее чем за 6 секунд (дополнительный кредит менее чем за 4,5 секунды).
Мне разрешено изменять только небольшой блок кода, и отправной точкой являетсянапример:
for (j=0; j < ARRAY_SIZE; j++) {
sum += array[j];
}
Где ARRAY_SIZE
равно 9973. Этот цикл содержится в другом цикле, который выполняется 200 000 раз.Эта конкретная версия запускается за 16 секунд.
Пока что я изменил реализацию, чтобы развернуть цикл и использовать указатели в качестве моего итератора:
(Эти объявления не зациклены на 200 000раз)
register int unroll_length = 16;
register int *unroll_end = array + (ARRAY_SIZE - (ARRAY_SIZE % unroll_length));
register int *end = array + (ARRAY_SIZE -1);
register int *curr_end;
curr_end = end;
while (unroll_end != curr_end) {
sum += *curr_end;
curr_end--;
}
do {
sum += *curr_end + *(curr_end-1) + *(curr_end-2) + *(curr_end-3) +
*(curr_end-4) + *(curr_end-5) + *(curr_end-6) + *(curr_end-7) +
*(curr_end-8) + *(curr_end-9) + *(curr_end-10) + *(curr_end-11) +
*(curr_end-12) + *(curr_end-13) + *(curr_end-14) + *(curr_end-15);
}
while ((curr_end -= unroll_length) != array);
sum += *curr_end;
Используя эти приемы, я смог сократить время исполнения до 5,5 секунд, что даст мне полную оценку.Тем не мение;Я действительно хочу заработать дополнительный кредит, но мне также любопытно, какие дополнительные оптимизации я могу сделать, чтобы я мог пропустить?
Редактировать # 1 (Добавление внешнего цикла)
srand(time(NULL));
for(j = 0; j < ARRAY_SIZE; j++) {
x = rand() / (int)(((unsigned)RAND_MAX + 1) / 14);
array[j] = x;
checksum += x;
}
for (i = 0; i < N_TIMES; i++) {
// inner loop goes here
if (sum != checksum)
printf("Checksum error!\n");
sum = 0;
}