Информация об изменениях

Сообщение Re[31]: Эльбрус - 8 ядер от 07.06.2017 23:00

Изменено 08.06.2017 5:53 vdimas

Re[31]: Эльбрус - 8 ядер
Здравствуйте, netch80, Вы писали:

V>>Верно, просто где-то слагаемое будет равно 0-лю или соотв. бит будет нулевой, если несколько счетчиков упакованы в одном слове.

N>Метод реализации тут действительно не сильно важен. Просто код вида
N>
N>  while (do1 || do2 || do3) {
N>    if (do1) { if (++cnt1 == lim1) { do1 = work1(); } else { delay_some(); } }
N>    if (do2) { if (++cnt2 == lim2) { do2 = work2(); } else { delay_some(); } }
N>    if (do3) { if (++cnt3 == lim3) { do3 = work3(); } else { delay_some(); } }
N>  }
N>

N>(ты ведь такое имел в виду?)

Конечно нет.
Условного ветвление не требуется в таких алгоритмах, по крайней мере в коде оперирования софтовыми таймерами.
Достаточны манипуляции с битами и простые арифметические операции:
unsigned step1;
unsigned step2;

unsigned acc1=0;
unsigned acc2=0;

while(true) {  
    acc1 += step1;
    acc2 += step2;
    byte result = ((acc1 & 0x80000000) >> 30) | ((acc2 & 0x80000000) >> 31);
    outp(some_port, result);

    calc_next_values_of_step1_and_step2();
}

Заметь, что пара управляющих сигналов выводятся синхронно.

Ну а для быстродейдствующей обработки какой-нить детали сначала высчитывается некий "батч" (как раз можно использовать время на обратный ход инструмента), а потом этот батч прогоняется, т.е. остальная часть может выглядеть примерно так:
unsigned steps1[];
unsigned index1 = 0;
unsigned steps2[];
unsigned index2 = 0;

void calc_next_values_of_step1_and_step2() {
    index1 += ((acc1 & 0x80000000) >> 31);
    step1 = steps1[index1];

    index2 += ((acc2 & 0x80000000) >> 31);
    step2 = steps2[index2];
}


Понятно, что операция навроде ((acc1 & 0x80000000) >> 31) вычисляется в реальности лишь однажды или вообще заменяется условным исполнением/пропуском (и всё-равно лишь однажды). Т.е. на асме это всё еще выразительней получается, бо в C++ слишком многословно и не верно. Там надо признак переполнения прибавить к индексу. Просто для выражения этого в С потребуется заводить переменную двойной ширины только ради опроса младшего бита старшего слова.


N>Так это, конечно, реализуемо, но не отвечает ни на один из поднятых мной вопросов о качестве синхронизации внешних акций в таком исполнении.


Согласен, твой код не отвечает ни на один из вопросов.
Более того, он позволяет делить тактовую частоту (пусть нам требуется в некоей задаче генерировать некую частоту) лишь на целые числа.


N>Ну вот я даже код навёл. Теперь скажи, что в нём не так, по твоему мнению.


В нём не так то, что ты хоть и работал со звуковой областью когда-то, но конкретно темы обработки звука не касался, похоже. Потому что если бы касался, то ты хотя бы раз в жизни писал генератор синусоиды, который пишется примерно так:
unsigned phase = 0;
unsigned delta = round(2*PI*freq/sample_rate);

unsigned sin_gen_next() {
    return fixed_point_sin(phase+=delta);
}

Заметь, не надо сравнивать на каждом шаге и по результату отнимать 2*PI.
Классика вычислений с фиксированной точкой — это масштабирование любых данных. В данном случае диапазон 0..2*PI отмасштабирован на диапазон 0..MAX_UINT. Причем, получили честную точность 32 разряда, в отличие от точности 24 разряда в случае использования float.


N>Он писался максимально близко к тому, как ты объясняешь.


Я вижу максимально далёкий код.


N>Ну вот я и включаю. Поведение подобных процессоров определено для такта, не так ли? Если на такте t поднялось прерывание таймера, то, например, на t+2 его заметил блок прерываний процессора, на t+3 уже пошла грузиться команда с нового адреса.


А еще надо запихать текущую инструкцию в стек.
А еще конвейер у нас может быть больше, чем 2 стадии, например 4 стадии. Итого, t+3+4. И запрет прерываний, пока один из таймеров обрабатываем.


N>(Предполагаю, что если думают о скорости, то отработка прерываний это сохранение PC+PSW в служебные регистры процессора и загрузка новых из таких же служебных, оперативная память тут не используется.)


В контроллерах его внутреннюю оперативную память можно рассматривать как продолжение файла регистров, там точно такая же скорость обращения, бо это регистровая память, как L0.


N>Декодиться и исполняться она будет, например, от t+4 до t+7. И что, эта поправка не может быть заложена в задание таймера?


А как ты думаешь, почему у "самоделкиных" их фрезерные и токарные станки работают примерно в 10-100 раз медленней, чем промышленные экземпляры?
Может от того, что при выдаваемой ими ужасной временнОй точности управления приходится в 10-100 раз снижать скорость перемещения резака относительно детали? ))

Разумеется, любую погрешность можно учесть и компенсировать, но я ж сходу упомянул, каким именно образом.


N>Да видел я их. Я не запоминаю, за отсутствием прямой необходимости, в какой из современных рахитектур какое именно убожество применено и выдано за новейшие достижения нейтринной мегалоплазмы


Дык, в архитектуре Intel с таймерами еще на пару порядков всё печальнее. Там вообще полная ж-па. У тебя на сегодня нет никакой возможности узнать текущее точное время. У тебя на выбор только правильно идущие часы с точностью ~1/64 сек или еще есть часы с хорошей точностью, но всегда идущие неправильно (query performance counter).


N>это счётчик времени


Ага. Тактовая этого счётчика какова? А разрядность? А время доступа к нему?


N>Ну тогда это порочный круг. Одни "спецы" вместо нормальных таймеров подсовывают тошнотворные пародии. Другие не просто соглашаются с этим работать (вместо того, чтобы вывалять первых в дёгте и перьях), но и хвалят свои решения, которые обходят проблемы этих пародий.

N>И это не только в таймерах, просто мы сейчас говорим о них.

Это дело привычки к определённому классу задач. Когда занимаешься этим постоянно, то подобные задачки решаются уже мозжечком, фактически не потребляя квантов внимания.

Просто ты заведомо неверно судишь о происходящем. Судить технические подходы можно лишь по некоторым критериям, где критерии обязательно зависят от самих же технических подробностей. ))

Ты же взял некие абстрактные критерии, где ни один из них не является важным для обсуждаемой предметной области.
Да тут не то, что в области низкоуровневых микроконтроллеров... тут даже в деле написания банальнейших дров под высокоуровневый ЦПУ на твоей машине — и уже твои критерии не работают. Ты слишком прикладной программист.


N>Отлично. А теперь скажи, что получится, если у тебя будет необходимость выполнить воздействие двум разным двигателям с интервалом меньше, чем эта длительность отработки одного двигателя. Например, work1() и delay() в коде выше — по 2 мкс, а тебе надо что-то сделать для 1 и 2 с разницей в 1 мкс.


Выделил ошибку.
Не у меня, а у тебя.
У тебя там не получится ничего, ес-но, как ты сам абсолютно правильно сейчас подметил.
Только зачем тогда было приводить заведомо неработающий код?
А потом ты обижаешься, когда я недвусмысленно намекаю, что ты ведешь обсуждение более чем странно, где странностью является добровольная бестолковость какая-то... ХЗ... никогда этого не пойму...


N>И что зависит от качества программистов для этих вспомогательных, кроме очевидного фактора корректности результата?


Тут тоже ХЗ. Но есть наблюдения — примерно половине программистов этот род деятельности не даётся вообще никак ни под каким видом. Хоть кол на голове им теши или даже под страхом расстрела. Казалось бы — там всё СЛИШКОМ элементарно... человек запросто пишет довольно-таки большие проги, использует сложные библиотеки и т.д... А вот просто пару бит туда-сюда погонять — полный ступор.


N>Я уже так давно не работал с SIP, что не могу понять, это в мой огород камень или нет. Но длинных цепочек ifʼов в своём коде я что-то не помню.


Если "раскрыть все скобки" (сделать все ф-ии инлайными в том коде), то будет просто масса ветвлений и всё.
Собсно, я еще тогда подробно объяснял этот фатальный недостаток SIP — это отсутствие встроенных ср-в комбинирования сценариев. Любая комбинация сценариев должна быть прописана в очередном расширении стандарта. Вот что я называю каменным веком. Протокол SIP был разработан, очевидно, потребителями технологий, а не производителями. Они взяли RTP, который был до них, они взяли TCP и сделали самую большую каку в истории VoIP. Более непоследовательного, непродуманного, ограниченного в развитии и т.д. до бесконечности протокола — просто не существует.

Мне SIP напоминает творчество тех самых админов Linux, где половина программы у них живет в конфиге, ы-ы-ы.
Одно плохо — придумать правильный формат конфига тоже моск нужен, а его при разработке SIP-а ни у кого не оказалось. ))
В общем, SIP был разработан админами, а не программистами, сие слишком очевидно.
Причем, очень и очень узкоспециализированным админами.
Поэтому, имеем что имеем.
Re[31]: Эльбрус - 8 ядер
Здравствуйте, netch80, Вы писали:

V>>Верно, просто где-то слагаемое будет равно 0-лю или соотв. бит будет нулевой, если несколько счетчиков упакованы в одном слове.

N>Метод реализации тут действительно не сильно важен. Просто код вида
N>
N>  while (do1 || do2 || do3) {
N>    if (do1) { if (++cnt1 == lim1) { do1 = work1(); } else { delay_some(); } }
N>    if (do2) { if (++cnt2 == lim2) { do2 = work2(); } else { delay_some(); } }
N>    if (do3) { if (++cnt3 == lim3) { do3 = work3(); } else { delay_some(); } }
N>  }
N>

N>(ты ведь такое имел в виду?)

Конечно нет.
Условного ветвления не требуется в таких алгоритмах, по крайней мере в коде оперирования софтовыми таймерами.
Достаточны манипуляции с битами и простые арифметические операции:
unsigned step1;
unsigned step2;

unsigned acc1=0;
unsigned acc2=0;

while(true) {  
    acc1 += step1;
    acc2 += step2;
    byte result = ((acc1 & 0x80000000) >> 30) | ((acc2 & 0x80000000) >> 31);
    outp(some_port, result);

    calc_next_values_of_step1_and_step2();
}

Заметь, что пара управляющих сигналов выводится синхронно.

Ну а для быстродейдствующей обработки какой-нить детали сначала высчитывается некий "батч" (как раз можно использовать время на обратный ход инструмента), а потом этот батч прогоняется, т.е. остальная часть может выглядеть примерно так:
unsigned steps1[];
unsigned index1 = 0;
unsigned steps2[];
unsigned index2 = 0;

void calc_next_values_of_step1_and_step2() {
    index1 += ((acc1 & 0x80000000) >> 31);
    step1 = steps1[index1];

    index2 += ((acc2 & 0x80000000) >> 31);
    step2 = steps2[index2];
}


Понятно, что операция навроде ((acc1 & 0x80000000) >> 31) вычисляется в реальности лишь однажды или вообще заменяется условным исполнением/пропуском (и всё-равно лишь однажды). Т.е. на асме это всё еще выразительней получается, бо в C++ слишком многословно и не верно. Там надо признак переполнения прибавить к индексу. Просто для выражения этого в С потребуется заводить переменную двойной ширины только ради опроса младшего бита старшего слова.


N>Так это, конечно, реализуемо, но не отвечает ни на один из поднятых мной вопросов о качестве синхронизации внешних акций в таком исполнении.


Согласен, твой код не отвечает ни на один из вопросов.
Более того, он позволяет делить тактовую частоту (пусть нам требуется в некоей задаче генерировать некую частоту) лишь на целые числа.


N>Ну вот я даже код навёл. Теперь скажи, что в нём не так, по твоему мнению.


В нём не так то, что ты хоть и работал со звуковой областью когда-то, но конкретно темы обработки звука не касался, похоже. Потому что если бы касался, то ты хотя бы раз в жизни писал генератор синусоиды, который пишется примерно так:
unsigned phase = 0;
unsigned delta = round(2*PI*freq/sample_rate);

unsigned sin_gen_next() {
    return fixed_point_sin(phase+=delta);
}

Заметь, не надо сравнивать на каждом шаге и по результату отнимать 2*PI.
Классика вычислений с фиксированной точкой — это масштабирование любых данных. В данном случае диапазон 0..2*PI отмасштабирован на диапазон 0..MAX_UINT. Причем, получили честную точность 32 разряда, в отличие от точности 24 разряда в случае использования float.


N>Он писался максимально близко к тому, как ты объясняешь.


Я вижу максимально далёкий код.


N>Ну вот я и включаю. Поведение подобных процессоров определено для такта, не так ли? Если на такте t поднялось прерывание таймера, то, например, на t+2 его заметил блок прерываний процессора, на t+3 уже пошла грузиться команда с нового адреса.


А еще надо запихать текущую инструкцию в стек.
А еще конвейер у нас может быть больше, чем 2 стадии, например 4 стадии. Итого, t+3+4. И запрет прерываний, пока один из таймеров обрабатываем.


N>(Предполагаю, что если думают о скорости, то отработка прерываний это сохранение PC+PSW в служебные регистры процессора и загрузка новых из таких же служебных, оперативная память тут не используется.)


В контроллерах его внутреннюю оперативную память можно рассматривать как продолжение файла регистров, там точно такая же скорость обращения, бо это регистровая память, как L0.


N>Декодиться и исполняться она будет, например, от t+4 до t+7. И что, эта поправка не может быть заложена в задание таймера?


А как ты думаешь, почему у "самоделкиных" их фрезерные и токарные станки работают примерно в 10-100 раз медленней, чем промышленные экземпляры?
Может от того, что при выдаваемой ими ужасной временнОй точности управления приходится в 10-100 раз снижать скорость перемещения резака относительно детали? ))

Разумеется, любую погрешность можно учесть и компенсировать, но я ж сходу упомянул, каким именно образом.


N>Да видел я их. Я не запоминаю, за отсутствием прямой необходимости, в какой из современных рахитектур какое именно убожество применено и выдано за новейшие достижения нейтринной мегалоплазмы


Дык, в архитектуре Intel с таймерами еще на пару порядков всё печальнее. Там вообще полная ж-па. У тебя на сегодня нет никакой возможности узнать текущее точное время. У тебя на выбор только правильно идущие часы с точностью ~1/64 сек или еще есть часы с хорошей точностью, но всегда идущие неправильно (query performance counter).


N>это счётчик времени


Ага. Тактовая этого счётчика какова? А разрядность? А время доступа к нему?


N>Ну тогда это порочный круг. Одни "спецы" вместо нормальных таймеров подсовывают тошнотворные пародии. Другие не просто соглашаются с этим работать (вместо того, чтобы вывалять первых в дёгте и перьях), но и хвалят свои решения, которые обходят проблемы этих пародий.

N>И это не только в таймерах, просто мы сейчас говорим о них.

Это дело привычки к определённому классу задач. Когда занимаешься этим постоянно, то подобные задачки решаются уже мозжечком, фактически не потребляя квантов внимания.

Просто ты заведомо неверно судишь о происходящем. Судить технические подходы можно лишь по некоторым критериям, где критерии обязательно зависят от самих же технических подробностей. ))

Ты же взял некие абстрактные критерии, где ни один из них не является важным для обсуждаемой предметной области.
Да тут не то, что в области низкоуровневых микроконтроллеров... тут даже в деле написания банальнейших дров под высокоуровневый ЦПУ на твоей машине — и уже твои критерии не работают. Ты слишком прикладной программист.


N>Отлично. А теперь скажи, что получится, если у тебя будет необходимость выполнить воздействие двум разным двигателям с интервалом меньше, чем эта длительность отработки одного двигателя. Например, work1() и delay() в коде выше — по 2 мкс, а тебе надо что-то сделать для 1 и 2 с разницей в 1 мкс.


Выделил ошибку.
Не у меня, а у тебя.
У тебя там не получится ничего, ес-но, как ты сам абсолютно правильно сейчас подметил.
Только зачем тогда было приводить заведомо неработающий код?
А потом ты обижаешься, когда я недвусмысленно намекаю, что ты ведешь обсуждение более чем странно, где странностью является добровольная бестолковость какая-то... ХЗ... никогда этого не пойму...


N>И что зависит от качества программистов для этих вспомогательных, кроме очевидного фактора корректности результата?


Тут тоже ХЗ. Но есть наблюдения — примерно половине программистов этот род деятельности не даётся вообще никак ни под каким видом. Хоть кол на голове им теши или даже под страхом расстрела. Казалось бы — там всё СЛИШКОМ элементарно... человек запросто пишет довольно-таки большие проги, использует сложные библиотеки и т.д... А вот просто пару бит туда-сюда погонять — полный ступор.


N>Я уже так давно не работал с SIP, что не могу понять, это в мой огород камень или нет. Но длинных цепочек ifʼов в своём коде я что-то не помню.


Если "раскрыть все скобки" (сделать все ф-ии инлайными в том коде), то будет просто масса ветвлений и всё.
Собсно, я еще тогда подробно объяснял этот фатальный недостаток SIP — это отсутствие встроенных ср-в комбинирования сценариев. Любая комбинация сценариев должна быть прописана в очередном расширении стандарта. Вот что я называю каменным веком. Протокол SIP был разработан, очевидно, потребителями технологий, а не производителями. Они взяли RTP, который был до них, они взяли TCP и сделали самую большую каку в истории VoIP. Более непоследовательного, непродуманного, ограниченного в развитии и т.д. до бесконечности протокола — просто не существует.

Мне SIP напоминает творчество тех самых админов Linux, где половина программы у них живет в конфиге, ы-ы-ы.
Одно плохо — придумать правильный формат конфига тоже моск нужен, а его при разработке SIP-а ни у кого не оказалось. ))
В общем, SIP был разработан админами, а не программистами, сие слишком очевидно.
Причем, очень и очень узкоспециализированным админами.
Поэтому, имеем что имеем.