Я выполняю вычисление трафаретов на матрице, которую я ранее читал из файла. Я использую два разных типа матриц (тип NonZero и нулевой тип). Оба типа разделяют значение границ (обычно 1000), в то время как остальные элементы равны 0 для типа "нуль" и 1 для типа NonZero.
Код хранит матрицу файла в двух распределенных матрицах одинакового размера. Затем он выполняет операцию в каждом элементе одной матрицы, используя ее собственное значение и значения соседей (добавить x 4 и mul x 1) и сохраняет результат во второй матрице. Как только вычисление завершено, указатели на матрицы меняются местами, и одна и та же операция выполняется в течение конечного количества раз. Здесь у вас есть код ядра:
#define GET(I,J) rMat[(I)*cols + (J)]
#define PUT(I,J) wMat[(I)*cols + (J)]
for (cur_time=0; cur_time<timeSteps; cur_time++) {
for (i=1; i<rows-1; i++) {
for (j=1; j<cols-1; j++) {
PUT(i,j) = 0.2f*(GET(i-1,j) + GET(i,j-1) + GET(i,j) + GET(i,j+1) + GET(i+1,j));
}
}
// Change pointers for next iteration
auxP = wMat;
wMat = rMat;
rMat = auxP;
}
В случае, когда я подвергаюсь воздействию, используется фиксированное количество 500 временных шагов (внешние итерации) и размер матрицы 8192 строк и 8192 столбца, но проблема сохраняется при изменении количества временных шагов или размера матрицы. Обратите внимание, что я только измеряю время этой конкретной части алгоритма, поэтому чтение матрицы из файла или ничего другого влияет на временную меру.
Что происходит, это то, что я получаю разные времена в зависимости от того, какой тип матрицы я использую, получая намного худшую производительность при использовании типа Zero (каждая другая матрица выполняет то же самое, что и тип NonZero, поскольку я уже пытался создать матрицу полный случайных значений).
Я уверен, что это операция умножения, как будто я удаляю ее и оставляю только добавление, они выполняют то же самое. Обратите внимание, что при нулевом матричном типе большая часть результата будет равна 0, поэтому операция будет "0.2 * 0".
Такое поведение, безусловно, странно для меня, поскольку я думал, что операции с плавающей запятой независимы от значений операндов, что здесь не похоже. Я также попытался захватить и показать исключения SIGFPE в случае, если это была проблема, но я не получил никаких результатов.
В случае, если это помогает, я использую процессор Intel Nehalem и gcc 4.4.3.