Комментарии 22
Я думаю, что замена многомерных массивов double[x,y] на одномерные double[x*y] даст неплохой прирост производительности. Не в 30 раз конечно но даст.

Далеко не факт.
Я не работал с C#, но на Java (понимаю что языки совершенно разные) приходилось иногда делать расчеты в многомерных массивах.
Очень и очень редко переход с n-мерных массивов к одномерному приводили к ускорению выполнения. В особо успешных случаях ускорение было, но на грани погрешности.
Смею предположить, что иногда компилятор или VM догадываются о том, что делает код и сами разворачивают его в один цикл.
Вполне возможно, что C# способен на такое.


Вообще лучше всего проверить на практике. У меня жаль под рукой C# нет

>Вполне возможно, что C# способен на такое.
Не не способен. Печаль в том что в .NET хорошо оптимизированы одномерные массивы, и вообще никак многомерные. К примеру доступ к элементу в одномерном массиве это IL opcode ld.elem, в многомерном это вызов метода на классе Array, который потом транслируется в кишки CLR. Так что разница может быть существенной.
Думаю вы правы, что это ускорило бы процесс. Только это потребовало бы уже гораздо больше усилий, чтобы перепахать всю внутреннюю логику на поддержку этого.
Имеет смысл для маленьких матриц, которые полностью влезут в кэш. Для больших матриц принципиальной разницы не будет ни на каком ЯП.
Здравый смысл подсказывает что многомерные (которые T[,] а не jugged вариант T[][]) массивы внутри устроены как обычные одномерные с трансляцией индексов вида
(i, j) -> i * dim(1) + j
(возможно с выравниванием), и вряд ли дадут значительное ускорение при ручном перепиливании.
Могут ли товарищи знакомые с кишками компилятора подтвердить или опровергнуть эту догадку?
Проверил, простое заполнение небольшого двумерного массива x,y проходит несколько медленнее, чем одномерного x*y.

int x, y, z;
int i, j, k;

x = 100;
y = 10;
z = 10000;

double[,] a = new double[x, y];
double[] b = new double[x * y];

Stopwatch stA = new Stopwatch();
stA.Start();

for (k = 0; k < z; k++)
for (i = 0; i < x; i++)
for (j = 0; j < y; j++)
a[i, j] = i * k;

stA.Stop();

Stopwatch stB = new Stopwatch();
stB.Start();

for (k = 0; k < z; k++)
for (i = 0; i < x * y; i++)
b[i] = i * k;

stB.Stop();

Results:

stA.Elapsed.Ticks = 531087
stB.Elapsed.Ticks = 390716
Интересно было бы про саму библиотеку прочесть в примерах. А если в двух словах, что в ней можно делать?
Кроме классических сетей (с реализацией обучения, отжига и т.д.) есть сети Хопфилда, самоорганизующиеся карты Кохонена. Вот тут куча примеров использования:

https://github.com/jeffheaton/jeffheaton-book-code/tree/master/CSIntroNeuralNetworkEdition2
Здорово получилось, конечно. Но что-то мне подсказывает, что переход на GPU обеспечит ускорение еще на порядок :)
Да, GPU показывает изумительные результаты. Я пробовал делать расчеты на GPU, оказалось там очень большие затраты на ввод вывод данных (вплоть до проигрыша CPU в сумме). Специфика моего приложения в том, что обмен данными очень интенсивный, такой что смысла юзать GPU не увидел.
Прежде еще можно задействовать SIMD (System.Numerics.Vectors) и переделать double на float.
Этот код у его автора на гитхабе лежит. Почему бы не запилить туда коммит для более всеобщей борьбы с энтропией?
«и глядя на загрузку CPU по 50-60% по телу бежал неприятный холодок — кто-то халтурит!» :)
Да это к счастью не проблема, загрузить проц весьма легко увеличив кол-во параллельно выполняющихся потоков в 1,5-2 раза, данный пример был для сравнимости результатов при одинаковом коде приложения (менялась только библиотека).
А статья для которой версии библиотеки? GetCol в текущей есть, но ни разу не используется. DotProduct вызывается в одном месте, не очень часто используемом. Можно попробовать сравнить с результатом, при использовании последней версии.
Интересно, какие задачи решаете с помощью этих сетей?
И какие максимальные размеры сеток (сколько слоев)
и входных таблиц (столбцов, строк) получается обрабатывать в этой библиотеке?
Проект — макроэкономическое моделирование. Надеюсь вскоре будут результаты достойные публикации. Размер сеток на данный момент 200x70x15 (три слоя).
Продолжаю любопытствовать. А топология которая используется? MLP?
Да, собственно топологии еще не перебирал (даже кол-во слоев не пробовал менять). Пока занимаюсь отладкой общей логики и функциональной обвязки (распределение вычислений по сети на несколько машин и агрегация результатов).
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.