Это сокращение, многие фреймворки (например, kokkos и cuda) поддерживают это сокращение. из скаляров, суммирующих число от каждого распараллеленного вычисления. Однако я хочу уменьшить матрицу.
Полученная матрица масштабируется в зависимости от размера задачи, но всегда остается намного меньше, чем количество распараллеленных вычислений. В каждую запись матрицы всегда вносятся несколько вкладов.
Мой код написан на C++, и в настоящее время я использую платформу Kokkos для распараллеливания.
Попытки
1
Я пробовал дать каждому потоку копию матрицы, копируя все это с устройства (графического процессора) на хост (процессор ) и суммируем их последовательно.- Требования к памяти графического процессора для всех матриц означали, что мне приходилось выполнять вычисления небольшими партиями
- Копирование данных с устройства на хост был огромным и неэффективным, просто подведем итоги позже.
- Время выполнения оказалось медленнее, чем последовательный метод.
2
Как и выше, но я выполнил последовательное суммирование на одном поток на устройстве (графический процессор) затем скопировал суммированную матрицу на хост- Ограничение памяти графического процессора остается тем же
- Последовательное суммирование в одном потоке графического процессора было очень медленным
- Минимальное время копирования в память
- Время выполнения почти соответствует последовательному методу
3
Я создал матрицу на стороне устройства с особенностью памяти Kokkos::Atomic, затем каждый поток + = его вклад в одну матрицу. Это основано на доступе к атомарной матрице для предотвращения коллизий. Затем я копирую эту матрицу на хост.- Это атомарная операция, ставящая под угрозу распараллеливание
- Минимальное время копирования в память
- В целом увеличение скорости на 20*, хорошо, но намного хуже, чем теоретический потенциал графического процессора (A100 с 10752) Ядра CUDA).
- Это схема, по которой я буду действовать, если не смогу сделать ничего лучше
Существует ли лучшая платформа на C++ со стандартизированной такой функциональностью.
Минимальный пример с атомарной матрицей:
#include
#include
int main(int argc, char *argv[]) {
Kokkos::initialize();
int matrix_size = 200;
int batches = 10;
Kokkos::View r("result_matrix", matrix_size,
matrix_size);
for (int batch = 0; batch < batches; batch++) {
Kokkos::parallel_for(
"populate", Kokkos::RangePolicy(0, 10752), KOKKOS_LAMBDA(const int i) {
//calculation goes here
//index and values should be calculated i dependent
r(42, 43) += 0.013;
r(42, 46) += 0.02;
});
}
auto h_r = Kokkos::create_mirror_view(r);
Kokkos::deep_copy(h_r, r);
std::cout
Подробнее здесь: https://stackoverflow.com/questions/793 ... tributions
Мобильная версия