Как стать автором
Обновить
-13
0

Пользователь

Отправить сообщение
Не вижу возможности вынести из циклов. Все зависит от [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++ есть несколько new, но ни одного delete...
Как ни странно, но в данном случае освобождение памяти средствами приложения вместо средств ОС только немного замедлит программу. ;)

На самом деле списывать надо на то, что вы не специались по распараллеливанию, как и не специалист по оптимизации...
О да, Intel VTune Amplifier спасет отца русской демократии:
https://habrahabr.ru/company/intel/blog/310842/
Cтоит попробовать вынести константные подвыражения из циклов.

Судя по ограничению скоростью памяти, вам стоит попробовать учесть иерархию памяти, чтобы повысить локальность обращений к памяти (процент попадания в кэш).
https://habrahabr.ru/post/312078/

Далее -march=native, векторизация (-sse2, avx), интринсики, профайлеры…

После чего становится грустно и взоры обращаются обратно к ANSYS ;)
Поскольку у меня нет машины с 12Г ОЗУ, спрошу здесь.
Как у него с классикой:
1. Эти типы стали…
2. На косой косе Косой…
Есть мнение, что ошибка была не в проектировании:
https://www.youtube.com/watch?v=I9zhjht4aaQ
Им уже не пофиг: У них есть есть такой класс железок как ALCS (Aux Load Control Switch), которые всегда готовы отключить твою нагрузку в самый интересный момент. Например кондиционер в самую жару, т. к. у энергетиков пик, а ЕЭС СЭВ, с ее экономией 12ГВт только на маневрах мощностями по 11 часовым поясам, бриты не осилили. Вот и страдают, бедные, несчастные.

Сайчас, в рамках вводимого стандарта цифрового-удаленного учета и отключения ресурсов GBCS все это только расширяется и углубливается.
12 ...
8

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность