Не вижу возможности вынести из циклов. Все зависит от [i][j]
for (int t = 1; t <= tMax; t++) { // begin main loop
float tt = Math.min(t * s + 10, ny - 1);
//gauss
switch (method) {
case "cos":
да, да конечно. Я понимаю, что это не самый внутренний цикл, но сравнение строк… Будем молиться, что компилятор сам раздвоит циклы для разных case (о чем бы было неплохо ему напомнить явно). Уж лучше лямбды/указатели на ф-ии, виртуальные методы в явном виде. Накрайняк — глобальный копипаст (как обычно, это всего быстрее:) ).
в
foreach (i)
x=f(i)
exp(-pow(x, 2) / w / w - (t - 1) * dt / tau)
я правильно понял, что
вся правя часть изменяется-таки от i и x и не может быть вынесена из цикла? Что-то я не верю, что компилятор матан учил лучше меня. Или там приколы с потерей точности?
pow(x, 2) это не x*x и вызов ф-ции (float,float) имеет смысл?
я Понимаю, что это вроде как мелкие придирки, но есть и более интересные замечания:
float **Hy = new float *[nx];
— массив указателей на массивы. Итого 2 обращения к памяти. Лучше уж глобальный
float XX[X][Y]
, что сведет операцию доступа к XX[x*Y+y]. Замечание: правильно назначьте X и Y, чтобы доступ к памяти был последовательным и хорошо ложился на prefetcher. И не надо бояться, что бинарник распухнет: эти массивы будут кратко описаны в сегменте zero-data.
Потом смотрим, что весь код у вас есть несколько циклов по nx при все увеличивающимся ny. Так мы имеем, что к следующему циклу по x строка уже выпала из кэша. Возможно имеет смысл сделать
for (int t = 1; t <= tMax; t++) {
for (i = 1; i <= nx - 1; i++) {
//gauss //для единственного i
// boundary conditions //для единственного i
....
Да, там придется подумать, чтобы не сломать математику, но такова судьба программиста-оптимизатора: записать алгоритм совершенно нечитаемо.
Дальше. Как уже говорили ниже
Все зависит от [i][j]
, но не для всех (i,j), а некой окрестности точки (i,j), что позволяет как повысить попадания в кэш, так и подумать за уменьшение выделенной памяти и массовое распаралеливание.
Cтоит попробовать вынести константные подвыражения из циклов.
Судя по ограничению скоростью памяти, вам стоит попробовать учесть иерархию памяти, чтобы повысить локальность обращений к памяти (процент попадания в кэш).
https://habrahabr.ru/post/312078/
Далее -march=native, векторизация (-sse2, avx), интринсики, профайлеры…
После чего становится грустно и взоры обращаются обратно к ANSYS ;)
Им уже не пофиг: У них есть есть такой класс железок как ALCS (Aux Load Control Switch), которые всегда готовы отключить твою нагрузку в самый интересный момент. Например кондиционер в самую жару, т. к. у энергетиков пик, а ЕЭС СЭВ, с ее экономией 12ГВт только на маневрах мощностями по 11 часовым поясам, бриты не осилили. Вот и страдают, бедные, несчастные.
Сайчас, в рамках вводимого стандарта цифрового-удаленного учета и отключения ресурсов GBCS все это только расширяется и углубливается.
да, да конечно. Я понимаю, что это не самый внутренний цикл, но сравнение строк… Будем молиться, что компилятор сам раздвоит циклы для разных case (о чем бы было неплохо ему напомнить явно). Уж лучше лямбды/указатели на ф-ии, виртуальные методы в явном виде. Накрайняк — глобальный копипаст (как обычно, это всего быстрее:) ).
в я правильно понял, что
я Понимаю, что это вроде как мелкие придирки, но есть и более интересные замечания:
— массив указателей на массивы. Итого 2 обращения к памяти. Лучше уж глобальный , что сведет операцию доступа к XX[x*Y+y]. Замечание: правильно назначьте X и Y, чтобы доступ к памяти был последовательным и хорошо ложился на prefetcher. И не надо бояться, что бинарник распухнет: эти массивы будут кратко описаны в сегменте zero-data.
Потом смотрим, что весь код у вас есть несколько циклов по nx при все увеличивающимся ny. Так мы имеем, что к следующему циклу по x строка уже выпала из кэша. Возможно имеет смысл сделать
Да, там придется подумать, чтобы не сломать математику, но такова судьба программиста-оптимизатора: записать алгоритм совершенно нечитаемо.
Дальше. Как уже говорили ниже , но не для всех (i,j), а некой окрестности точки (i,j), что позволяет как повысить попадания в кэш, так и подумать за уменьшение выделенной памяти и массовое распаралеливание.
О да, Intel VTune Amplifier спасет отца русской демократии:
https://habrahabr.ru/company/intel/blog/310842/
Судя по ограничению скоростью памяти, вам стоит попробовать учесть иерархию памяти, чтобы повысить локальность обращений к памяти (процент попадания в кэш).
https://habrahabr.ru/post/312078/
Далее -march=native, векторизация (-sse2, avx), интринсики, профайлеры…
После чего становится грустно и взоры обращаются обратно к ANSYS ;)
Как у него с классикой:
1. Эти типы стали…
2. На косой косе Косой…
https://www.youtube.com/watch?v=I9zhjht4aaQ
Сайчас, в рамках вводимого стандарта цифрового-удаленного учета и отключения ресурсов GBCS все это только расширяется и углубливается.