2014-09-26 2 views
0

Я пытаюсь проверить свой сложный векторный код матрицы CSR на системе с 2 процессорами, имеющими по 6 ядер каждый. Я неожиданно получаю почти то же время для 1, 2, 4, 6 или 12 потоков. Он работает, и я вижу, что соответствующие потоки живы во время умножения, но не ускоряют то, что так когда-либо. Я не понимаю, допустила ли я какую-то ошибку или просто не могла решить проблему.OpenMP Нет производительности: Вложенный цикл

void spmv_csr(int num_rows, const int* rowPtrs, const int* colIdxs, const double complex* values, const double complex* x, double complex* y) 
{ 
    double complex rowSum; 
    int i, j, row_start, row_end; 
    clock_t begin, end; 
    begin = clock(); 
    #pragma omp parallel for private(j, i, row_start, row_end) reduction(+:rowSum) 
    for(i = 0; i < num_rows; i++) 
    { 
    rowSum = 0.00 + 0.00 *I; 
    row_start = rowPtrs[i]-1; 
    row_end = rowPtrs[i+1]-1; 
    for (j=row_start; j<row_end; j++) 
    { 
     rowSum += ((creal(values[j]) * creal(x[colIdxs[j]-1])) - (cimag(values[j]) * cimag(x[colIdxs[j]-1]))) + (((creal(values[j]) * cimag(x[colIdxs[j]-1])) + (cimag(values[j]) * creal(x[colIdxs[j]-1]))) * I); 
    } 
    y[offset+i] = rowSum; 
    } 
    end = clock(); 
    printf("Time Elapsed: %f seconds\n", (double)(end - begin)/CLOCKS_PER_SEC); 

}

я получаю около 0,38 сек для бега с 1, 2, 4, 6, 8, 12 нитей, я не понимаю, почему я даже не видя 10% прирост скорости.

Спасибо за любые входные данные заранее.

+0

Все ли темы работали одновременно? Я бы назвал функцию omp_get_num_threads(), чтобы узнать, действительно ли программа использует многоядерный процессор. – Juniar

+1

Возможный дубликат недавнего вопроса, который является дубликатом вопроса, который является дубликатом [более старого вопроса] (http://stackoverflow.com/questions/10673732/openmp-time-and-clock-calculates-two-different -results) - не используйте 'clock()'. Кроме того, ваш код привязан к памяти и с большой производительностью матриц не будет масштабироваться. –

+0

@Hristo Iliev Возможно, но это задал другой пользователь. Однако вам, возможно, придется перенаправить его, чтобы узнать, что он спрашивает. – Juniar

ответ

1

Похоже, что переменная уменьшения rowSum становится точкой сериализации. Поскольку rowSum не только накапливается как сумма, но также считывается с (y [offset + i] = rowSum;), он должен быть сериализован.

Если вы хотите, чтобы rowSum пересекался только с одной строкой, я бы удалил сокращение и сделаю его закрытым. Я хотел бы изменить прагму к:

#pragma omp parallel for private(j, i, row_start, row_end, rowSum) 

Если вы планируете для rowSum быть в общей сложности во всех рядах, я хотел бы использовать мой выше предложение, чтобы получить параллелизм, и затем использовать префикс-сумму, чтобы изменить у после этого, чтобы получить правильные итоги.

Смежные вопросы