У меня есть следующая функция:
void ikj(float (*a)[N], float (*b)[N], float (*c)[N], int n) {
int i, j, k;
float r;
papi_start();
for (i = 0; i < n; i++) {
for (k = 0; k < n; k++) {
r = a[i][k];
for (j = 0; j < n; j++)
c[i][j] += r * b[k][j];
}
}
papi_stop();
}
И я использую PAPI
посчитать, сколько грузов и магазинов у меня между papi_start()
а также papi_stop()
и результаты, которые я имею, следующие:
Нагрузки (используя PAPI_LD_INS
):
32 26781
64 205053
128 1606077
256 12714815
512 101189551
1024 807406950
2048 6450848188
Магазины (используя PAPI_SR_INS
):
32 8290
64 65698
128 524578
256 4194850
512 33555490
1024 268437701
2048 2147487778
где первое значение — это размер N, а второе — количество инструкций.
я компилирую с O3 и размеры моего кеша составляют L1 = 32 КБ х 2 (инструкция и данные, 8-полосная) и L2 = 1024 КБ (4-полосная) (общая для 2 ядер) .. мой процессор — Intel T3200 и есть SSE3 ..
Я знаю, что O3 оптимизирует код, поэтому он будет использовать предварительную выборку среди других функций, и так как я загружаю смежные адреса, и мой кэш имеет размер строки 64 байта, я загружаю 16 операций с плавающей запятой за раз, но мои вычисления не достигают этого ценности, так кто-нибудь может мне это объяснить?
РЕДАКТИРОВАТЬ: Это мои файлы сборки, извините, что просто выбросить их здесь, но я никогда не работал со сборкой, и я не могу понять, что из этого:
http://dl.dropboxusercontent.com/u/878621/mmc.s
http://dl.dropboxusercontent.com/u/878621/mmc_asm.s
Спасибо!
Глядя на магазины, число, которое вы получаете, очень близко к N**3 / 4
, Мы ожидаем, что это будет O (N ** 3), очевидно.
Это говорит о том, что 4 записи с плавающей запятой объединяются в одно из значений, измеряемых PAPI_SR_INS. Глядя на это в качестве альтернативы, вы рассчитываете число 16-байтовых записей.
Точно так же количество нагрузок примерно 3/4 N**3
, Доминирующим слагаемым должна быть нагрузка от b и c внутри самого внутреннего цикла, которая будет равна 2 чтениям за итерацию. Честно говоря, я не могу понять это.
Если вы не знаете точно, что вы измеряете, и не коррелируете это с сгенерированным кодом, довольно сложно предсказать измерение.
РЕДАКТИРОВАТЬ: числа, кажется, соотносятся с выполненными инструкциями загрузки и сохранения, но не с количеством транзакций L1, L2 и т. Д. Или пропущены — поэтому вряд ли коррелируют с фактической производительностью. Разве время лучше не стоит беспокоиться? Учитывая сложность современной архитектуры ЦП, я бы доверял измерениям, а не прогнозированию в любой день.
Других решений пока нет …