Сначала - Вам не нужен навигатор; SelectNodes / SelectSingleNode должен быть достаточным.
Вам, возможно, однако, понадобится менеджер пространства имен - например:
XmlElement el = ...; //TODO
XmlNamespaceManager nsmgr = new XmlNamespaceManager(
el.OwnerDocument.NameTable);
nsmgr.AddNamespace("x", el.OwnerDocument.DocumentElement.NamespaceURI);
var nodes = el.SelectNodes(@"/x:outerelement/x:innerelement", nsmgr);
Возможно, вам понадобится четыре цикла - два для итерации по блокам, а затем еще два для выполнения транспонирования-копии одного блока. Предполагая для простоты размер блока, который делит размер матрицы, я думаю, что-то вроде этого, хотя я бы хотел нарисовать некоторые картинки на обороте конвертов:
for (int i = 0; i < n; i += blocksize) {
for (int j = 0; j < n; j += blocksize) {
// transpose the block beginning at [i,j]
for (int k = i; k < i + blocksize; ++k) {
for (int l = j; l < j + blocksize; ++l) {
dst[k + l*n] = src[l + k*n];
}
}
}
}
Важное дальнейшее понимание состоит в том, что на самом деле для этого есть алгоритм, не обращающий внимания на кеш (см. http://en.wikipedia.org/wiki/Cache-oblivious_algorithm , в котором в качестве примера используется именно эта проблема). Неформальное определение «не обращающего внимания на кэш» заключается в том, что вам не нужно экспериментировать с настройкой каких-либо параметров (в данном случае размера блоков), чтобы достичь хорошей / оптимальной производительности кэша. Решением в этом случае является транспонирование путем рекурсивного деления матрицы пополам и перемещения половин в их правильное положение в пункте назначения.
Каким бы ни был размер кэша, эта рекурсия использует его в своих интересах. Я ожидаю, что по сравнению с вашей стратегией возникнут некоторые дополнительные издержки на управление, заключающиеся в том, чтобы использовать эксперименты с производительностью, чтобы, по сути, перейти прямо к той точке рекурсии, в которой кэш действительно срабатывает, и не идти дальше. С другой стороны, ваши эксперименты с производительностью могут дать вам ответ, который работает на вашей машине, но не на машинах ваших клиентов.
Вместо транспонирования матрицы в памяти, почему бы не свернуть операцию транспонирования в следующую операцию, которую вы собираетесь выполнить с матрицей?