Давайте начнем с первого вопроса: имеет ли смысл транспонировать?Ответ, это зависит, и вы можете оценить, улучшит ли это вещи или нет.
Транспонирование / ретранспозиция с наложением единовременной стоимости пропускной способности памяти 2 * (быстрый просмотр памяти) +2 * (медленный путь через память), где эти операции с памятью являются буквально операциями с памятью в многоядерном случае или сетевыми связями в случае распределенной памяти.Вы будете читать матрицу быстрым способом и медленно помещать ее в память.(Вы можете сделать это, по сути, 4 * (проходя через память быстрым способом), читая матрицу в одном блоке размера кэша за раз, транспонируя в кэш и выполняя запись в порядке).
Является ли это выигрышем или нет, зависит от того, сколько раз вы будете обращаться к массиву.Если бы вы ударили 4 раза по всему нетранспонированному массиву с доступом к памяти в «неправильном» направлении, то вы явно выиграете, выполнив две транспонирования.Если вы будете проходить через неперемещенный массив только один раз в неправильном направлении, то вы почти наверняка не выиграете, выполнив транспозицию.
Что касается более крупного вопроса, @AlexandreC абсолютно прав здесь- пытаться реализовать свои собственные процедуры линейной алгебры - это безумие.Посмотрите, например, Как написать быстрый числовой код , рисунок 3;между наивными и хорошо настроенными (скажем, GEMM) операциями может быть коэффициент 40.Эти вещи сильно ограничены в пропускной способности памяти, а параллельно это означает ограниченную сеть.Безусловно, лучше всего использовать существующие инструменты.
Для многоядерной линейной алгебры, существующие библиотеки включают в себя
Для реализаций MPI существует
или полная решающая среда, такая как