Очень низкая производительность cusparse csrsv_analysis

Я написал решатель Conjugate-gradient (для линейной системы уравнений) с предварительной обработкой LU, я использовал документы в исследовательском сообществе nvidia в качестве руководства, этап обновления остатков, который требует решения системы нижней треугольной матрицы, а затем решения системы верхней треугольной матрицы, разделен на две фазы. :

  1. фаза анализа (которая использует шаблон разреженности и определяет уровень параллелизации).
  2. сам этап решения.

согласно всем сообщениям, связанным с этой темой, и самой статье Наумова, фаза анализа значительно медленнее, чем фаза решения, но выполняется один раз, поэтому это не должно быть проблемой, если принять во внимание все время выполнения, однако, в моей программе фаза анализа требует ~35-45% всего времени решения (время, необходимое для выполнения всех итераций!), что довольно раздражает, другое дело, что я совершенно уверен, что шаблон разреженности матрицы не позволяют в значительной степени распараллеливать, так как почти все элементы требуют, чтобы были известны предыдущие элементы (поскольку в CFD каждому узлу потребуются по крайней мере 6 соседних узлов (шестигранные объемы) вокруг него, и это повторяется в каждой строке), поэтому этап анализа все равно не очень пригодится!

matrixLU в этом коде содержит как верхнюю, так и нижнюю треугольные матрицы, верхняя треугольная матрица использует диагонали исходной матрицы, а нижняя треугольная матрица имеет единичные диагонали (LU-факторизация).

// z = inv(matrixLU)*r
cusparseMatDescr_t descrL = 0 ;
cusparseMatDescr_t descrU = 0 ;
cusparseStatus = cusparseCreateMatDescr(&descrL) ;
cusparseStatus = cusparseCreateMatDescr(&descrU) ;

cusparseSetMatType(descrL,CUSPARSE_MATRIX_TYPE_GENERAL) ;
cusparseSetMatIndexBase(descrL,CUSPARSE_INDEX_BASE_ONE) ;
cusparseSetMatDiagType(descrL,CUSPARSE_DIAG_TYPE_UNIT) ;
cusparseSetMatFillMode(descrL,CUSPARSE_FILL_MODE_LOWER) ;

cusparseSetMatType(descrU,CUSPARSE_MATRIX_TYPE_GENERAL) ;
cusparseSetMatIndexBase(descrU,CUSPARSE_INDEX_BASE_ONE) ;
cusparseSetMatDiagType(descrU,CUSPARSE_DIAG_TYPE_NON_UNIT) ;
cusparseSetMatFillMode(descrU,CUSPARSE_FILL_MODE_UPPER) ;

cusparseSolveAnalysisInfo_t inforL = 0 ;
cusparseSolveAnalysisInfo_t inforU = 0 ;
cusparseStatus = cusparseCreateSolveAnalysisInfo(&inforL) ;
cusparseStatus = cusparseCreateSolveAnalysisInfo(&inforU) ;

double startFA = omp_get_wtime() ;
cusparseStatus = cusparseDcsrsv_analysis(cusparseHandle, CUSPARSE_OPERATION_NON_TRANSPOSE, N, NZ, descrL, matrixLU, iRow, jCol, inforL) ;
if(cusparseStatus != CUSPARSE_STATUS_SUCCESS) printf("%s \n\n","cusparseDcsrsv_analysis1 Error !") ;
cusparseStatus = cusparseDcsrsv_analysis(cusparseHandle, CUSPARSE_OPERATION_NON_TRANSPOSE, N, NZ, descrU, matrixLU, iRow, jCol, inforU) ;
if(cusparseStatus != CUSPARSE_STATUS_SUCCESS) printf("%s \n\n","cusparseDcsrsv_analysis2 Error !") ;
double finishFA = omp_get_wtime() ;

Итак, кто-нибудь понял, почему фаза анализа такая медленная? и как его можно ускорить? зависит ли (время выполнения фазы анализа)/(время выполнения фазы решения) ratio от GPU?

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

  • Размер (N): ~860 000 * 860 000
  • Количество ненулевых значений (Новая Зеландия): ~6 000 000
  • Количество итераций, необходимых для сходимости: 10
  • Время выполнения фазы Анализ: 210 мс
  • Время выполнения фазы решения (сумма всех итераций): 350 мс
  • Все операции с плавающей запятой выполняются в формате двойной точности.
  • Графический процессор: GeForce GTX 550 Ti
  • ОС: Windows 7 максимальная, 64-разрядная

person Alphajet    schedule 08.07.2012    source источник
comment
Каковы размеры задач, GPU и операционная система, на которых вы запускаете этот код?   -  person talonmies    schedule 08.07.2012
comment
@talonmies, я добавил информацию в редактирование, большое спасибо за беспокойство, нужно ли что-то еще для построения общей картины? Я боролся с этим в течение нескольких дней!   -  person Alphajet    schedule 08.07.2012


Ответы (1)


Я связался с нашей командой библиотек линейной алгебры в NVIDIA, и они предоставили следующие отзывы.

  1. По результатам работы:

    1. Итерационный метод КГ выполняет всего 10 итераций, пока не будет найдено решение линейной системы. Кажется, что в данном случае итераций недостаточно, чтобы амортизировать время, затраченное на фазу анализа. (Правка:) Количество шагов, необходимых для сходимости к решению, различается в разных приложениях. В некоторых необусловленных итерационных методах не сходятся (или требуются тысячи итераций), а предварительно обусловленные итерационные методы требуют десятков (или сотен) итераций для сходимости к решению. Тот факт, что в этом конкретном приложении итерационный метод сходится за 10 итераций, не обязательно репрезентативен для всех приложений.

    2. Соотношение фаз анализа и решения составляет 6 = 210/35, что согласуется с нашими экспериментами на других матрицах, где оно обычно находится в интервале [4,10]. Неясно, как время на этапы анализа и решения соотносится со временем, затрачиваемым на разреженное треугольное решение на ЦП. (Было бы интересно узнать эту информацию.)

  2. With respect to the algorithm:
    1. Unfortunately, there are only a few things you can do to recover a little bit of performance (there is no real way to speed up the analysis phase). For example, you can split the matrixLU into separate lower and upper triangular parts. Computing with separate triangular parts is in general faster than computing with triangular parts embedded in a general matrix. If you are using incomplete factorization with 0 fill-in as a preconditioner, you can also take advantage of the incomplete-LU/Cholesky with 0 fill-in on the GPU, that has recently become available in the CUSPARSE library. (Edit:) The incomplete-LU factorization with 0 fill-in is available in CUDA Toolkit 5.0 release. Currently the early access version of this release can be obtained by registered developers on the NVIDIA website.
    2. Мы никогда не смотрели, как соотношение между этапами анализа и решения зависит от разных графических процессоров; все наши эксперименты проводились на C2050.
    3. Фаза анализа выполняется медленно, потому что она должна собирать информацию о том, какие строки могут быть объединены в уровни. Фаза решения выполняется быстрее, потому что она обрабатывает только уровни (см. rel="noreferrer">данный документ).

Наконец, вы также упомянули, что, по вашему мнению, в задаче недостаточно параллелизма. Но количество параллелизма может быть трудно определить, просто взглянув на матрицу. Если параллелизма действительно мало (каждая строка зависит от предыдущей строки), то разреженное треугольное решение CUSPARSE может оказаться неподходящим алгоритмом для этой задачи. Кроме того, вы можете попробовать запустить итеративный метод компьютерной графики без предварительных условий или с другими типами предварительных условий, которые могут больше подойти для вашей задачи.

Как упоминалось ранее, было бы интересно узнать, как производительность этого кода сравнивается на GPU и CPU.

Редактировать: Относительно некоторых комментариев... Как упоминалось ранее, максимальное количество итераций для предобусловленного итеративного метода различается в разных приложениях. В некоторых случаях оно может быть очень маленьким (например, 10, как в вашем приложении), но в других случаях оно может быть относительно большим (измеряется в сотнях). В статье основное внимание уделяется не «триумфу», а скорее компромиссам алгоритма. Он пытается дать пользователю более глубокое понимание процедуры, чтобы ее можно было эффективно использовать. Опять же, если имеющийся шаблон разреженности не имеет никакого параллелизма, этот алгоритм вам не подходит.

Что касается сравнения ЦП и ГП, то есть определенные задачи (например, умножение плотной матрицы на матрицу или разреженное умножение матрицы на вектор), для которых отлично подходит ГП, а есть и другие (например, обход связанного списка или выполнение полностью последовательного фрагмента кода). код), для которого это не так. Решение разреженных треугольных линейных систем находится где-то посередине между этими алгоритмами (в зависимости от шаблона разреженности матрицы коэффициентов и других свойств линейной системы это может работать или не работать для вас). Кроме того, решение об использовании графического процессора основывается не только на одном алгоритме, таком как разреженное треугольное решение, но и на всем наборе алгоритмов, используемых приложением. В конечном счете, графические процессоры часто очень успешно ускоряют и улучшают производительность всего приложения.

Наконец, что касается сравнения trsm и csrsv, нас не удивляет, что для небольших матриц выполнение операций в плотном хранилище выполняется быстрее, чем в разреженном (даже если эти маленькие матрицы могут быть разреженными). Обычно это верно не только для треугольного решения, но и для других операций линейной алгебры (хотя это может происходить в разных точках пересечения в зависимости от операции и шаблона разреженности матрицы). Кроме того, еще раз, алгоритм разреженного треугольного решения был разработан для работы в итеративной настройке, когда анализ выполняется один раз, а решение выполняется несколько раз. Таким образом, неудивительно, что ее однократный запуск (и подсчет на этапе анализа) приводит к более высокой точке пересечения, чтобы эта операция была более эффективной в разреженном, а не в плотном формате.

person harrism    schedule 12.07.2012
comment
Прежде всего, я хотел бы поблагодарить вас за ваш исчерпывающий ответ, я с нетерпением ждал этого. Позвольте мне ответить вам по пунктам, как и вы: 1.1. Смысл использования LU или предварительной обработки Холецкого заключается в минимизации количества итераций, поэтому меньшее количество итераций является особенностью предварительной обработки, и решатель должен быть оптимизирован для таких случаев. - person Alphajet; 12.07.2012
comment
1.2. Я уже сравниваю свой код со многими мощными версиями ЦП (MKL и другими кодами, написанными в нашей компании), предварительно подготовленная версия CG с диагональным масштабированием была быстрее на GPU, в то время как предварительно подготовленная версия LU была намного медленнее. - person Alphajet; 12.07.2012
comment
2.1. Я прочитал статью доктора Наумова (research.nvidia.com/publication/), в котором описывается, как построить LU или факторизацию Холецкого, но, согласно последней документации cUSparse, нет функции для создания предобуславливателя, но, пожалуйста, дайте мне знать, если есть, Это было бы очень полезно. - person Alphajet; 12.07.2012
comment
2.2. Было бы здорово сделать такие тесты и опубликовать их. - person Alphajet; 12.07.2012
comment
2.3. Я не понимаю, как доктор Максим может считать ускорение фазы решения над MKL триумфом, если он использует 1300-долларовую Tesla C2050 против 300-долларового intel i7 950, я думаю, сравнение некорректно, к тому же выигрыш в ускорении приобретается, если этап решения повторяется несколько раз, что в некоторых случаях может быть высоким, в то время как предварительное обусловливание обычно требуется для уменьшения количества итераций. - person Alphajet; 12.07.2012
comment
Итак, в целом меня очень интересуют следующие моменты: 1. Доступна ли факторизация Холецкого в CuSparse? какая версия ? 2. CG с диагональным масштабированием на GPU опережала CPU версии, а версии LU и Cholesky были значительно медленнее, исключительно из-за фазы анализа. 3. Я попробую использовать компьютерную графику без предварительных условий вместо треугольного решателя и дам вам знать, что получилось. Заранее спасибо @harrism - person Alphajet; 12.07.2012
comment
Я попрошу у Максима дополнительные комментарии (у него нет аккаунта SO), но на ваш комментарий по сравнению perf/$. Tesla C2050 — это процессор класса HPC с оперативной памятью SSE на борту. Intel i7 — это процессор потребительского класса, который не содержит оперативной памяти. Чтобы провести справедливое сравнение цен, вам нужно будет включить стоимость оперативной памяти SSE, если не процессора Xeon (класса HPC). Это будет гораздо больше, чем 300 долларов. - person harrism; 13.07.2012
comment
Среди всех версий компьютерной графики для ЦП, которые я пробовал для решения наших задач, предварительно подготовленная версия LU была самой быстрой, версия LU для ЦП быстрее, чем версия с диагональным масштабированием для графического процессора, поэтому я заинтересован в использовании CUDA для написания Решатель компьютерной графики с предварительной обработкой LU, мне все время интересно, есть ли способ просто пропустить фазу анализа или указать ему передать одноуровневую информационную структуру по умолчанию? - person Alphajet; 13.07.2012
comment
В основном я сравниваю GTX 550 Ti с Intel i7 950, как я уже упоминал ранее, предварительно подготовленная компьютерная графика с диагональным масштабированием была быстрее на GPU, а не на CPU, она была даже немного медленнее, чем Xeon X5680! Итак, мы очень заинтересованы в использовании графических процессоров Tesla, но сначала мне нужно найти способ ускорить алгоритм компьютерной графики с предварительной обработкой LU. - person Alphajet; 13.07.2012
comment
Я добавил правки выше. Вот вопросы? 1.2: какой фактической производительности вы достигли? - person harrism; 23.07.2012
comment
@harrism Прошло 18 месяцев с тех пор, как этот вопрос был поднят. CUDA 5.0 отсутствует, а CUSPARSE общедоступен. Однако я не могу найти исчерпывающий ресурс — например, высокоуровневую библиотеку — для разреженных решателей GPU. Каково текущее (почти 2014 год) состояние этих кодов? - person BrianTheLion; 20.12.2013