тест скорости high-low

Тема в разделе "Arduino & Shields", создана пользователем DrProg, 4 июл 2015.

  1. DrProg

    DrProg Вечный нерд

    Просьба ко всем, особенно у кого есть оригинальная MEGA уделить 1 минуту времени, запустить приведенный ниже скетч на своем девайсе и посмотреть цифру которую он выдаст в мониторе порта. Заранее спасибо.
    Код (Text):
    #define DATA_PIN    13
    #define LATCH_PIN  12
    #define CLOCK_PIN  11

    #define kadrTime    100 // мс на кадр
    #define kadrov      4 // колво кадров


    byte masRG [4][8][8] = {
      0, 0, 0, 0, 0, 0, 0, 0, // 1
      0, 1, 1, 1, 1, 1, 1, 0,
      0, 1, 3, 3, 3, 3, 1, 0,
      0, 1, 3, 2, 2, 3, 1, 0,
      0, 1, 3, 2, 2, 3, 1, 0,
      0, 1, 3, 3, 3, 3, 1, 0,
      0, 1, 1, 1, 1, 1, 1, 0,
      0, 0, 0, 0, 0, 0, 0, 0,

      1, 1, 1, 1, 1, 1, 1, 1, //2
      1, 3, 3, 3, 3, 3, 3, 1,
      1, 3, 2, 2, 2, 2, 3, 1,
      1, 3, 2, 0, 0, 2, 3, 1,
      1, 3, 2, 0, 0, 2, 3, 1,
      1, 3, 2, 2, 2, 2, 3, 1,
      1, 3, 3, 3, 3, 3, 3, 1,
      1, 1, 1, 1, 1, 1, 1, 1,

      3, 3, 3, 3, 3, 3, 3, 3, // 3
      3, 2, 2, 2, 2, 2, 2, 3,
      3, 2, 0, 0, 0, 0, 2, 3,
      3, 2, 0, 1, 1, 0, 2, 3,
      3, 2, 0, 1, 1, 0, 2, 3,
      3, 2, 0, 0, 0, 0, 2, 3,
      3, 2, 2, 2, 2, 2, 2, 3,
      3, 3, 3, 3, 3, 3, 3, 3,

      2, 2, 2, 2, 2, 2, 2, 2, // 4
      2, 0, 0, 0, 0, 0, 0, 2,
      2, 0, 1, 1, 1, 1, 0, 2,
      2, 0, 1, 3, 3, 1, 0, 2,
      2, 0, 1, 3, 3, 1, 0, 2,
      2, 0, 1, 1, 1, 1, 0, 2,
      2, 0, 0, 0, 0, 0, 0, 2,
      2, 2, 2, 2, 2, 2, 2, 2
    };


    long unsigned int ts; // таймер кадров
    byte kadrV; // видимый кадр

    // для подсчета fps
    long unsigned int ttt;
    unsigned int sss = 0;
    unsigned int fps = 0;

    void setup() {
      pinMode(DATA_PIN, OUTPUT);
      pinMode(CLOCK_PIN, OUTPUT);
      pinMode(LATCH_PIN, OUTPUT);
      kadrV = 0;
      ts = millis();
      Serial.begin(9600);
    }

    void loop() {

      if ((millis() - ts) >= kadrTime) { // циклическое чередование кадров
        kadrV++;
        if (kadrV >= kadrov) kadrV = 0;
        ts = millis();
      }
      setKadr_RG(masRG, kadrV); // отрисовка кадра

    // подсчет fps
      fps++;
        if ((millis() - ttt) > 2000) {
          Serial.println(fps);
        while (true);
        }

    }
    void setKadr_RG (byte mRG[2][8][8], byte kadr) { // отрисовка кадра
      byte bytSTR;
      byte mR;
      byte mG;
      for (byte s = 0; s <= 7; s++) {
        bytSTR = 0;
        bitSet(bytSTR, s);
        for (byte i = 0; i <= 7; i++) {
          bitWrite(mR, i, !(bitRead(mRG[kadr][s][i], 0)));
          bitWrite(mG, i, !(bitRead(mRG[kadr][s][i], 1)));
        }
        digitalWrite(LATCH_PIN, LOW);
        writeByte(bytSTR);
        writeByte(mR);
        writeByte(mG);
        digitalWrite(LATCH_PIN, HIGH);
      }
    }

    void writeByte(byte byteW) { // аналог shiftOut, работает чуть быстрее
      for (int i = 7; i >= 0; i--) {
        digitalWrite(DATA_PIN, (bitRead(byteW, i)));
        digitalWrite(CLOCK_PIN, HIGH);
        digitalWrite(CLOCK_PIN, LOW);
      }
    }
     
     
  2. Alex19

    Alex19 Гуру

    Mega 2560 R3 оригинал, Arduino IDE 1.0.6
    стабильно - 419, сделал 3 теста
     
    DrProg нравится это.
  3. DrProg

    DrProg Вечный нерд

    Спасибо большое!
     
  4. Alex19

    Alex19 Гуру

    Не за что, удачи, код не смотрел.

    Немного поменяв, получил - 2112, можно наверно еще оптимизировать. Сколько надо получить?

    UPD. Решил немного просмотреть, очень странные строки.
    Код (Text):
    long unsigned int ts; // таймер кадров
    Код (Text):
    long unsigned int ttt;
    Что за тип данных, long или int?
     
    Последнее редактирование: 5 июл 2015
  5. DrProg

    DrProg Вечный нерд

    Длинный инт беззнаковый
    0 / 4 294 967 295

    Что именно оптимизировали? Надо бы чтоб работоспособность не пропала при этом.

    Собственно этим кодом я скорее проверял производительность платы, которая у меня вызывала сомнения. Действительно неродная Мега выдала 375, а родная Уно 458. Завтра поменяю Мегу на другую, проверенную.

    Но все равно интересно что вы оптимизировали ускорив программу в 4,5 раза при этом ничего не сломав, скопируйте пожалуйста.
     
    Последнее редактирование: 5 июл 2015
  6. Alex19

    Alex19 Гуру

    Могу ошибаться, пользуюсь uint32_t для unsigned long, но в ардуине вроде объявляется так
    Код (Text):
    unsigned long time;
    Глянул тут - https://www.arduino.cc/en/Reference/UnsignedLong.

    Сделал только прямой доступ к портам на AVR

    .ino
    Код (Text):

    #include "FastIO.h"

    #define DATA_PIN    13
    #define LATCH_PIN  12
    #define CLOCK_PIN  11

    #define kadrTime    100 // мс на кадр
    #define kadrov      4 // колво кадров


    byte masRG [4][8][8] = {
      0, 0, 0, 0, 0, 0, 0, 0, // 1
      0, 1, 1, 1, 1, 1, 1, 0,
      0, 1, 3, 3, 3, 3, 1, 0,
      0, 1, 3, 2, 2, 3, 1, 0,
      0, 1, 3, 2, 2, 3, 1, 0,
      0, 1, 3, 3, 3, 3, 1, 0,
      0, 1, 1, 1, 1, 1, 1, 0,
      0, 0, 0, 0, 0, 0, 0, 0,

      1, 1, 1, 1, 1, 1, 1, 1, //2
      1, 3, 3, 3, 3, 3, 3, 1,
      1, 3, 2, 2, 2, 2, 3, 1,
      1, 3, 2, 0, 0, 2, 3, 1,
      1, 3, 2, 0, 0, 2, 3, 1,
      1, 3, 2, 2, 2, 2, 3, 1,
      1, 3, 3, 3, 3, 3, 3, 1,
      1, 1, 1, 1, 1, 1, 1, 1,

      3, 3, 3, 3, 3, 3, 3, 3, // 3
      3, 2, 2, 2, 2, 2, 2, 3,
      3, 2, 0, 0, 0, 0, 2, 3,
      3, 2, 0, 1, 1, 0, 2, 3,
      3, 2, 0, 1, 1, 0, 2, 3,
      3, 2, 0, 0, 0, 0, 2, 3,
      3, 2, 2, 2, 2, 2, 2, 3,
      3, 3, 3, 3, 3, 3, 3, 3,

      2, 2, 2, 2, 2, 2, 2, 2, // 4
      2, 0, 0, 0, 0, 0, 0, 2,
      2, 0, 1, 1, 1, 1, 0, 2,
      2, 0, 1, 3, 3, 1, 0, 2,
      2, 0, 1, 3, 3, 1, 0, 2,
      2, 0, 1, 1, 1, 1, 0, 2,
      2, 0, 0, 0, 0, 0, 0, 2,
      2, 2, 2, 2, 2, 2, 2, 2
    };


    long unsigned int ts; // таймер кадров
    byte kadrV; // видимый кадр

    // для подсчета fps
    long unsigned int ttt;
    unsigned int sss = 0;
    unsigned int fps = 0;

    void setup() {
      MC_SET_PIN_OUTPUT(DATA_PIN);
      MC_SET_PIN_OUTPUT(CLOCK_PIN);
      MC_SET_PIN_OUTPUT(LATCH_PIN);
      kadrV = 0;
      ts = millis();
      Serial.begin(9600);
    }

    void loop() {

      if ((millis() - ts) >= kadrTime) { // циклическое чередование кадров
        kadrV++;
        if (kadrV >= kadrov) kadrV = 0;
        ts = millis();
      }
      setKadr_RG(masRG, kadrV); // отрисовка кадра

    // подсчет fps
      fps++;
        if ((millis() - ttt) > 2000) {
          Serial.println(fps);
        while (true);
        }

    }
    void setKadr_RG (byte mRG[2][8][8], byte kadr) { // отрисовка кадра
      byte bytSTR;
      byte mR;
      byte mG;
      for (byte s = 0; s <= 7; s++) {
        bytSTR = 0;
        bitSet(bytSTR, s);
        for (byte i = 0; i <= 7; i++) {
          bitWrite(mR, i, !(bitRead(mRG[kadr][s][i], 0)));
          bitWrite(mG, i, !(bitRead(mRG[kadr][s][i], 1)));
        }
        MC_WRITE_PIN(LATCH_PIN, LOW);
        writeByte(bytSTR);
        writeByte(mR);
        writeByte(mG);
        MC_WRITE_PIN(LATCH_PIN, HIGH);
      }
    }

    void writeByte(byte byteW) { // аналог shiftOut, работает чуть быстрее
      for (int i = 7; i >= 0; i--)
      {
        MC_WRITE_PIN(DATA_PIN, (bitRead(byteW, i)));
        MC_WRITE_PIN(CLOCK_PIN, HIGH);
        MC_WRITE_PIN(CLOCK_PIN, LOW);
      }
    }
    FastIO.h в прищепке.

    Может еще можно что-то сделать, вопрос надо ли. Но уже туплю.
     

    Вложения:

    • FastIO.txt
      Размер файла:
      41,7 КБ
      Просмотров:
      318
    DrProg нравится это.
  7. DrProg

    DrProg Вечный нерд

    А, ну долгий стандартный доступ к портам это вопрос известный, да. Но пока критического момента не наступило, пользуюсь ими. За библиотеку спасибо, я ей буду пользоваться.

    Кононично объявлять unsigned long time;, но компилятор понимает и long unsignet time; видел в каком то примере, так и написал.
     
    Последнее редактирование: 5 июл 2015
  8. DrProg

    DrProg Вечный нерд

    Тоже туплю, в какую папку записать *.h чтобы его было видно компилятору?
     
  9. Alex19

    Alex19 Гуру

    Можно пробовать работу с байтами, как на AVR, возможно будет быстрее, не проверял. Так же в циклах for использовать не ++, а --. Но раз не критично, можно забыть, лишний раз усложнять код не стоит.

    Меня удивило в строке - long unsigned int ts, long и int одновременно.

    Отправил на почту, это урезанный и измененный код
    Код (Text):
    Based on: fastio.h - https://github.com/MarlinFirmware/Marlin/tree/Release/Marlin
    Там больший список AVR процессоров и другая стилистика, исправлял под себя, когда разбирался в нужных мне функциях.

    Если Arduino IDE в туже папку, рядом с ino.

    UPD. Библиотека отличная, она сделана очень достойно и заточена под платы ардуино, так как принимает номера пинов ардуины.
     
  10. DrProg

    DrProg Вечный нерд

    Разобрался, спасибо, буду пробовать.
     
  11. Alex19

    Alex19 Гуру

    В папку библиотек, не поймет, руки не доходят сделать в виде библиотеки. Иногда Arduino IDE тупит, просто добавьте вкладку назовите FastIO.h и скопируйте содержание файла.

    [​IMG]
     
    Последнее редактирование: 5 июл 2015
  12. DrProg

    DrProg Вечный нерд

    Да нормально он подгрузился из папки со скетчем. Вопрос чисто из любопытства: посмотрел бегло этот файл, там самого кода и нет, сплошные определения и переопределения, как он вообще работает то?

    Да, и почему -- быстрее чем ++?
     
  13. Alex19

    Alex19 Гуру

    А не заметил, если коротко, он работает на ## (очень мощный инструмент препроцессора Си, ознакомится можно тут), прямого доступа к портам, битовых операций, определения самого процессора, макросов плюс константы, которые содержат сами порты. Все под определенные процессоры AVR.

    Если все эти темы, хотя бы бегло просмотреть, все сложится.
     
  14. DrProg

    DrProg Вечный нерд

    Поразительная разница в скорости! Почему в IDE это не используют? Из за проблем с совместимостью с другими процессорами?
     
  15. Alex19

    Alex19 Гуру

    Если Вы просто, будете использовать простой прямой доступ (можно ознакомится тут), скорость будет одинаковая, может быть немного быстрее этой библиотеки. Она позволяет переносить код на разные процессоры AVR, те которых нет, можно дописать.

    Почему ее нет в стандартной IDE, а зачем?
    Кому надо, тот разберется с конкретным процессором/найдет библиотеку и т.д.

    UPD. Сложно сказать почему ее нет среди стандартных. Возможно из-за каких-то тонкостей о которых не знаю.

    Если меня не устраивает скорость, иду в Си, кто-то опускается в ассемблер, такой код сложнее и требует больших знаний. Порой проще взять более мощный процессор, туже DUE и т.д.
     
    Последнее редактирование: 5 июл 2015
  16. DrProg

    DrProg Вечный нерд

    С последним абзацем согласен, то же самое написано и по вашей ссылке: "Ваше время дорого, не так ли? А время компьютера очень дешево, соизмеримо со стоимостью потребленного им электричества." Но, как минимум, надо знать, что есть возможность прилично ускорить при необходимости некоторые критические части программы. Мало ли какие задачи могут внезапно возникнуть.

    Для LCD 16x2 есть такой же чудо-файлик? )
     
    Последнее редактирование: 5 июл 2015
  17. Alex19

    Alex19 Гуру

    Видимо вчера пропустил, не заметил. Подумал, что Вам нужна именно скорость, поэтому и предложил данную библиотеку.

    Если нет необходимости в скорости, то нет смысла использовать такие библиотеки. Мне всегда не нравится, если я использую код или библиотеку и у меня нет понимания как она работает. Всегда разбираюсь, хотя бы те методы с которыми работаю.

    Речь идет только о циклах. Это сборная информация из сети, сам еще не добрался проверять, к примеру вот составные части 1, 2, всех статей не упомню.

    Нет, не было необходимости.
     
  18. Megakoteyka

    Megakoteyka Оракул Модератор

    Когда в цикле используется --, происходит сравнение с нулем, это одна инструкция. В случае ++ происходит сравнение с некоторым значением, которое для сравнения нужно сперва загрузить в регистр, получается уже две инструкции.
     
  19. Unixon

    Unixon Оракул Модератор

    1) В библиотеке Wiring, а не в IDE! IDE - это просто редактор текста с кнопочками.
    2) Откоровенно никакая переносимость кода между разными контроллерами.

    Подход Wiring с универсальными функциями довольно хреновый по скорости, да еще с добавлением новых контроллеров будет становиться только хуже. Гораздо правильнее генерировать универсальный код с помощью шаблонов C++ с небольшой примесью макросов. Что-то похожее сделано, например, в библиотеке USB Host Shield 2.0 (см. avrpins.h). Так генерируется не универсальные функции, содержащие логику для вычисления портов и битов для всех контроллеров сразу, а только для текущего контроллера, что намного эффективнее и по скорости и по памяти тоже. При этом сохраняется переносимость кода и внешне он не усложняется. А этот FastIO - это еще ерунда, так, зачатки какие-то.
     
  20. Unixon

    Unixon Оракул Модератор

    Используются шаблоны следующим образом. Сначала объявляются шаблонные классы для отдельных функций контроллера. Для ввода-вывода, например, это шаблон класса пина, который параметризуется портом и битом, этот класс содержит методы работы с одним битом (чтение, установка, инверсия, подтяжка, и т.п.). Потом пишется шаблон устройства и параметризуется классами пинов. В результате вы переезжая с контроллера на контроллер каждый раз генерируете только нужный код, а весь остальной так и остается в исходнике.
     
    Alex19 нравится это.