Исходя из анализа ассемблера в трассе он не может быть быстрее чем asmopt - судите сами:
// скорее всего это iload_3
0x7fffe49216c3: movzbl 0x1(%r13),%ebx
0x7fffe49216c8: inc %r13
0x7fffe49216cb: movabs $0x7ffff7d7ebc0,%r10
0x7fffe49216d5: jmpq *(%r10,%rbx,8)
// скорее всего это iload_1
0x7fffe49215be: push %rax
0x7fffe49215bf: mov -0x8(%r14),%eax
0x7fffe49215c3: movzbl 0x1(%r13),%ebx
0x7fffe49215c8: inc %r13
0x7fffe49215cb: movabs $0x7ffff7d7ebc0,%r10
0x7fffe49215d5: jmpq *(%r10,%rbx,8)
В обоих командах повторяется загрузка константы в %r10 с помощью movabs - в asmopt адрес таблицы всегда лежит в регистре. Та же история повторяется и дальше в каждой операции.
Первая команда вообще ничего не делает кроме продвижения к следующему байткоду (или перед ней есть что-то содержательное и трасса обрезана неправильно)
Идем дальше:
// скорее всего это if_icmpge 34
0x7fffe49253c7: mov (%rsp),%edx
0x7fffe49253ca: add $0x8,%rsp
0x7fffe49253ce: cmp %eax,%edx
0x7fffe49253d0: jl 0x7fffe4925413
0x7fffe4925413: movzbl 0x3(%r13),%ebx
0x7fffe4925418: add $0x3,%r13
0x7fffe492541c: movabs $0x7ffff7d813c0,%r10
0x7fffe4925426: jmpq *(%r10,%rbx,8)
Тут происходит чтение из стека 4 байт, сдвиг его указателя как если бы мы прочитали 8 байт а дальше начинается ерунда: jl прыгает на адрес, который идет сразу за ним, но этот адрес на 0x43 отстоит от jl. Т.е. очевидно, что трасса показана неправильно и автор вообще ничего не понимает в ассемблере, иначе бы не допустил такую ошибку.
Дальше смотреть не стал, с такими исходными данными не может быть доверия к выводам на их основе. А без знания ассемблера говорить о производительности интерпретаторов/компиляторов - беспредметно.
Если я не ошибся в интерпретации транзисторной схемы, то я вижу два каскада усиления (на VT1-VT2 и VT3-VT4. Но я не могу взять в толк, как именно "Сигнал с несущей частотой F1" эта схема превращает в "Сигнал на выходе приемника"
Хорошая статья, спасибо. Очень интересно было бы узнать подходы к изготовлению устройств, которые могут обмениваться информацией по ИК-каналу. Я бы хотел иметь возможность включить что-то дистанционно пультом или флиппером, не вставая со стула, но ничего не знаю о том как можно спроектировать такое устройство. Фоторезисто за инфракрасным фильтром был бы вариантом, но, непонятно как выделить несущую, особенно если длительность пиков может плавать
Я пожалуй воздержусь от спора. Иначе тут будет затратное мероприятие по отводу аргументов лернейской гидры - с одним справился, тут тебя еще десятью закидают :) Специалист извлечет для себя методы и подходы из статьи, баталии в комментариях - это непродуктивный спор с теми, кто, к сожалению, не сможет улучить время в бенчмарке.
java запускалась без jit-компиляции. В обоих случаях измеряется полное время программы, с любой подготовкой контекста, запуском и остальными приготовлениями.
Не совсем. Нам никто не мешает запустить несколько потоков в каждом из которых будет своя виртуальная машина - это будет классическая многопоточность, где у каждой ВМ есть свой стек, но при этом могут быть общие области памяти (и критические секции)
Спасибо, я не знал про подход с таймером.
Думаю это потрясающая работа, я бы хотел отслеживать ее — возможно какие-то замечания помогут сделать ее лучше. Почему бы вам не начать ее на гитхабе?
Отличная работа!
«Нижний уровень GDB-сервера выполнен с использованием библиотеки WinUSB.» — а что работает на кристалле? Вот за этим наверняка стоит куча всего интересного, что стоило бы рассмотреть. Тогда каждый смог бы по такому туториалу написать себе remote debugger хоть на AVR. Я бы хотел прочитать такой туториал!
Правильно ли я понимаю, что теперь я могу делать чисто консольное приложение в терминале с отображением графики (если требуется взаимодействие только с клавиатурой)? Есть ли какой-то образец, чтобы посмотреть как это возможно?
Читая один из интересных прикладных документов я наткнулся на такой пассаж:
В семействе AVR различают три типа оперативной памяти: регистры, порты и собственно память. Для доступа к каждому из них существуют особенные команды (MOV, IN, OUT, LDS, STS). По сути они выполняют одно и тоже — копирование байт из одного места в другое, только они еще явно указывают к какому типу памяти будет происходить обращение.
Всё было хорошо, пока однажды команда OUT не смогла отправить байт в настроечный порт. Оказалось, что данный порт переехал в ОЗУ и теперь к нему нужно обращаться через STS
Написал слова IN и OUT, которые по адресу операндов определяют в какую память идет обращение и компилируют соответствующую команду. Оказалось удобно: code AAA \ пример использования «умного» IN
in r0,r1
in r1,portB
in r0,0x60
c;
code BBB \ пример использования «умного» OUT
out r0,r1
out portB,r1
out 0x60,r0
c;
и вот что получилось: AAA: MOV R0,R1
IN R1,PORTB
LDS R0,0x60
BBB: MOV R0,R1
OUT PORTB,R1
STS 0x60,R0
Я понимаю трудности автора с ассемблером AVR в разных моделях контроллеров и ранее решал такое макросами ассемблера, но этот подход показался мне интереснее и гибче — он не привязан к конкретному ассемблеру и выбор способа ассемблирования тем не менее происходит во время компиляции.
Что вы думаете о таком методе? Может быть я не вижу его недостатков?
Есть все-таки небольшая разница между луддизмом и амишами. Луддиты хотели запретить машины для всех, а это сообщество всего лишь ограничивает применение машин для себя. Да еще и подходит к этому ограничению весьма креативно
Было бы очень интересно прочесть статью, хотя бы с поверхностным обзором всего этого
Исходя из анализа ассемблера в трассе он не может быть быстрее чем asmopt - судите сами:
В обоих командах повторяется загрузка константы в %r10 с помощью movabs - в asmopt адрес таблицы всегда лежит в регистре. Та же история повторяется и дальше в каждой операции.
Первая команда вообще ничего не делает кроме продвижения к следующему байткоду (или перед ней есть что-то содержательное и трасса обрезана неправильно)
Идем дальше:
Тут происходит чтение из стека 4 байт, сдвиг его указателя как если бы мы прочитали 8 байт а дальше начинается ерунда: jl прыгает на адрес, который идет сразу за ним, но этот адрес на 0x43 отстоит от jl. Т.е. очевидно, что трасса показана неправильно и автор вообще ничего не понимает в ассемблере, иначе бы не допустил такую ошибку.
Дальше смотреть не стал, с такими исходными данными не может быть доверия к выводам на их основе. А без знания ассемблера говорить о производительности интерпретаторов/компиляторов - беспредметно.
Если я не ошибся в интерпретации транзисторной схемы, то я вижу два каскада усиления (на VT1-VT2 и VT3-VT4. Но я не могу взять в толк, как именно "Сигнал с несущей частотой F1" эта схема превращает в "Сигнал на выходе приемника"
Возможно не совсем корректно убирать печать. Я еще не проверял, но могу продположить что Java-вариант должен оптимизировать
if (isPrime) System.out.printf("[%d]\n", i);
убирая соответствующие байткоды, а в отключенном asmexp убирается только сам вызов функции, судя по патчу, накладные расходы остаются
Я думаю, что просто не могу не оставить это тут: https://lex-kravetski.livejournal.com/253994.html
Хорошая статья, спасибо. Очень интересно было бы узнать подходы к изготовлению устройств, которые могут обмениваться информацией по ИК-каналу. Я бы хотел иметь возможность включить что-то дистанционно пультом или флиппером, не вставая со стула, но ничего не знаю о том как можно спроектировать такое устройство. Фоторезисто за инфракрасным фильтром был бы вариантом, но, непонятно как выделить несущую, особенно если длительность пиков может плавать
Я пожалуй воздержусь от спора. Иначе тут будет затратное мероприятие по отводу аргументов лернейской гидры - с одним справился, тут тебя еще десятью закидают :) Специалист извлечет для себя методы и подходы из статьи, баталии в комментариях - это непродуктивный спор с теми, кто, к сожалению, не сможет улучить время в бенчмарке.
java запускалась без jit-компиляции. В обоих случаях измеряется полное время программы, с любой подготовкой контекста, запуском и остальными приготовлениями.
Не совсем. Нам никто не мешает запустить несколько потоков в каждом из которых будет своя виртуальная машина - это будет классическая многопоточность, где у каждой ВМ есть свой стек, но при этом могут быть общие области памяти (и критические секции)
Думаю это потрясающая работа, я бы хотел отслеживать ее — возможно какие-то замечания помогут сделать ее лучше. Почему бы вам не начать ее на гитхабе?
«Нижний уровень GDB-сервера выполнен с использованием библиотеки WinUSB.» — а что работает на кристалле? Вот за этим наверняка стоит куча всего интересного, что стоило бы рассмотреть. Тогда каждый смог бы по такому туториалу написать себе remote debugger хоть на AVR. Я бы хотел прочитать такой туториал!
Я понимаю трудности автора с ассемблером AVR в разных моделях контроллеров и ранее решал такое макросами ассемблера, но этот подход показался мне интереснее и гибче — он не привязан к конкретному ассемблеру и выбор способа ассемблирования тем не менее происходит во время компиляции.
Что вы думаете о таком методе? Может быть я не вижу его недостатков?