Автор Тема: Очень простой цикл  (Прочитано 56590 раз)

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #135 : Июнь 07, 2012, 02:22:36 pm »
2 Kemet
Зачем?
Ну или условие изменить

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #136 : Июнь 07, 2012, 02:36:29 pm »
Так зачем? Там ошибка?

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #137 : Июнь 07, 2012, 02:40:05 pm »
Напряг извилины и родил алгоритм A0 который прыгает на 2 позиции
А если попробовать прыгать на три позиции?
WHILE (a[i] # 0) OR ((a[i - 1] # 0) & (a[i + 1] # 0)) DO
i := i + 3
END;

Правда, тогда размер массива должен быть кратен и двум, и трём...

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #138 : Июнь 07, 2012, 03:49:23 pm »
А если попробовать прыгать на три позиции?

Следующие улучшения алгоритма буду сильно зависеть от характера входных данных. Придумать что-то более эффективное для "общего" случая трудно. Причем даже "прыгающий" алгоритм может оказаться хуже самого простого на конкретной железке/компиляторе.

P.S. Вообще изначально вопрос ставился не о самом эффективном по скорости, а о самом правильном (по сумме критериев) цикле :)

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #139 : Июнь 07, 2012, 03:53:34 pm »
Прыжки туда-сюда могут привести к увеличению промахов кэша. Ну и ветвления вообще неплохо тормозят систему (сбивается предсказывалка переходов). Но это все конечно действительно СИЛЬНО от железяки зависит. Скажем если мы пишем под процессор msp430, то нам на это пофиг, ибо там нет ни кэша ни предсказаний переходов :-) Зато есть табличка где четко указана стоимость каждой из инструкций в тактах.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #140 : Июнь 07, 2012, 04:06:41 pm »
P.S. Вообще изначально вопрос ставился не о самом эффективном по скорости, а о самом правильном (по сумме критериев) цикле :)
Я понял задачу буквально - простой цикл и один единственный, т.е. решить задачу используя один цикл, без вспомогательных механизмов и библиотечных методов, разруливая состояния условиями вхождения и IF'ами внутри цикла.

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #141 : Июнь 07, 2012, 04:20:24 pm »
Сергей, есть возможность мой говнокод прогнать тоже?  ::)
Я затрудняюсь адекватно перевести его на ансэйфный C# в варианте без заранее известной длины массива (чтобы адекватно сравнить с предыдущими). В результате творческого пересказа у меня получается что-то вроде такого:

static long A5 (char* begin)
{
   char* next = begin + 1;
   bool BREAK = false;
   while (!BREAK)
   {
      if (*next == 0)
      {
         if (*(next-1) == 0)
         {
            BREAK = true;
         }
         else
         {
            next++;
         }
      }
      else
      {
         next += 2;
      }
   }
   return (long)(next - begin) - 1;
}

Время его выполнения такое же как и у A0

A5:
2.9989265 seconds
2.9958975 seconds
2.9939577 seconds

A0:
2.9941996 seconds
2.9946799 seconds
2.9830016 seconds

Если рукопашный костыль BREAK заменить на встроенный в C# костыль break, то скорость выполнения не меняется.

----------

Занимательное наблюдение: если в главном if-е инвертировать условие:

   if (*next != 0)
   {
      next += 2;
   }
   else if (*(next-1) == 0)
   {
      BREAK = true;
   }
   else
   {
      next++;
   }

то скорость работы существенно замедляется (до 4.26 секунды). Видимо в тройном if-else_if-else ошибается процессорный блок отвечающий за спекулятивное выполнение обеих веток if-else.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #142 : Июнь 07, 2012, 04:26:18 pm »
Напряг извилины ....

Круто! Значительно проще чем у меня  :)

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #143 : Июнь 07, 2012, 06:29:51 pm »
Прыжки туда-сюда могут привести к увеличению промахов кэша. Ну и ветвления вообще неплохо тормозят систему (сбивается предсказывалка переходов). Но это все конечно действительно СИЛЬНО от железяки зависит. Скажем если мы пишем под процессор msp430, то нам на это пофиг, ибо там нет ни кэша ни предсказаний переходов :-) Зато есть табличка где четко указана стоимость каждой из инструкций в тактах.
Так не в коде прыгать. В данных. Тогда получится, что условие цикла будет меньшее количество раз проверяться (в полтора раза).

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #144 : Июнь 07, 2012, 06:47:22 pm »
Прыжки туда-сюда могут привести к увеличению промахов кэша. Ну и ветвления вообще неплохо тормозят систему (сбивается предсказывалка переходов). Но это все конечно действительно СИЛЬНО от железяки зависит. Скажем если мы пишем под процессор msp430, то нам на это пофиг, ибо там нет ни кэша ни предсказаний переходов :-) Зато есть табличка где четко указана стоимость каждой из инструкций в тактах.
Так не в коде прыгать. В данных. Тогда получится, что условие цикла будет меньшее количество раз проверяться (в полтора раза).
Именно прыжки в данных и могут приводить к увеличению промахов кэша.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #145 : Июнь 07, 2012, 06:57:20 pm »
А разве в данном случае не без разницы?

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #146 : Июнь 07, 2012, 07:48:10 pm »
Кстати: "инвариант цикла не является единственным".
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #147 : Июнь 07, 2012, 08:02:26 pm »
Кстати: "инвариант цикла не является единственным".
:D ;)

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #148 : Июнь 07, 2012, 08:17:38 pm »
Кстати: "инвариант цикла не является единственным".
:D ;)
С этого на самом деле можно долго кормиться требуя выдать единственно верный инвариант данного конкретного цикла.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #149 : Июнь 08, 2012, 10:39:41 am »
Новый рекорд поставлен алгоритмом A6 (взял алгоритм A0 и немножко раскрыл цикл вручную).

static long A6 (char* begin)
{
   char* p = begin + 1;
   do
   {
      while (*p != 0)
      {
         if (*(p+2) == 0)
         {
            p += 2;
         }
         else if (*(p+4) == 0)
         {
            p += 4;
         }
         else if (*(p+6) == 0)
         {
            p += 6;
         }
         else if (*(p+8) == 0)
         {
            p += 8;
         }
         else
         {
            p += 10;
         }
      }
      p--;
   }
   while (*p != 0);
   return (long)(p - begin);
}

Добавление следующей ветки с прыжком на +12 позиций перестало давать улучшение и даже наоборот сильно ухудшило результат, поэтому остановился на прыжке в +10 позиций.

Итого (делалось по три прогона):

A6:
1.9233069 seconds
1.9081622 seconds
1.9067381 seconds

A0:
2.9498565 seconds
2.9519935 seconds
2.95218 seconds

A5:
2.9516315 seconds
2.9512815 seconds
2.9507045 seconds

A1:
3.0003191 seconds
3.0015618 seconds
3.002155 seconds

A2:
5.5711093 seconds
5.5719351 seconds
5.571565 seconds

A3:
5.5734382 seconds
5.5723023 seconds
5.572676 seconds

A4:
6.7624739 seconds
6.7605317 seconds
6.7603002 seconds