Ответы пользователя по тегу Процессоры
  • Существует RISC процессоры с архитектурой фон Неймана?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Обычно RISC процессоры строят по Гарвардской архитектуре, а CISC - по архитектуре фон Неймана. Бывают другие варианты?

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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Когда эмулятор собирает и компилирует код jit, то как он этот код в машинных инструкциях составляет.

    Если ты посмотришь на QEMU, то у него есть фронт-енды (https://github.com/qemu/qemu/tree/v8.1.0/target), каждый из которых транслирует инструкции эмулируемой машины в промежуточный код. И есть бэк-енды (https://github.com/qemu/qemu/tree/v8.1.0/tcg), каждый из которых транслирует инструкции промежуточного кода в инструкции хостовой машины. Каждая гостевая инструкция может превратиться во множество промежуточных, а каждая промежуточная -- во множество хостовых. У разработчиков есть правило, что если на гостевую инструкцию требуется больше 20 промежуточных, то вместо прямой трансляции такая инструкция реализуется как вызов функции на C. Инструкции транслируются базовыми блоками, с заданного адреса и до достижения одного из следующих условий: 1) встречена инструкция выполняющая переход (условный или безусловный, вызов функции, возврат из функции, сюда же относятся инструкции гарантированно вызывающие исключение), или 2) PC переходит через границу страницы виртуальной памяти, или 3) количество инструкций в базовом блоке превышает заданный предел. Вдобавок с каждым оттранслированным базовым блоком ассоциируется дополнительный набор флагов, определяемый фронт-ендом, который кодирует состояние, в котором была машина при трансляции этого кода. Это позволяет иметь несколько вариантов трансляции для кода начинающегося с одного и того же адреса, например для разных уровней привилегий. Оттранслированные базовые блоки помещаются в кеш с функцией поиска по комбинации адреса и дополнительного набора флагов. В цикле выполнения эмулятор ищет транслированный базовый блок кода в кеше (а если не находит его, то транслирует и помещает в кеш), запускает его и получает контроль после завершения его выполнения.

    надо к примеру Перед выполнением каждой инструкции проверять наличие прерывания

    Вовсе не каждой, даже в 100% точной эмуляции нужно проверять IRQ только когда прерывания разрешены. QEMU обычно проверяет запрос на прерывание только перед входом в оттранслированный базовый блок.

    Или же есть несколько блоков, где линейно выполняется весь блок, а последняя инструкция прыгнет в другой блок.

    Да, QEMU выполняет трансляцию базовыми блоками.

    к примеру для вот такого примера графа, сколько базовых блоков можно построить?

    В этом графе не обозначены безусловные переходы, если их нет, то QEMU мог бы выделить такие базовые блоки: 0-1-2-3, 4-5-6, 7-8-1-2-3, 9-10, 11-12-13, 14-15-16-2-3, 17, всего 7 блоков.
    Если безусловные переходы -- это все переходы от узлов с бОльшими номерами к узлам с меньшими, то картина была бы такой: 0-1-2-3, 4-5-6, 7-8, 1-2-3, 9-10, 11-12-13, 14-15-16, 2-3, 17. Да, фрагмент 2-3 оттранслирован три раза: сам по себе и в составе других блоков.
    Ответ написан
    2 комментария
  • Существует ли 100% свободный процессор?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    существует ли 100% свободный процессор

    Существует несколько открытых реализаций risc-v: https://en.wikipedia.org/wiki/RISC-V#Open_source наверняка среди них есть и свободные.
    Ответ написан
    Комментировать
  • Как реализовать виртуальный кеш, tlb?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как реализованы в kvm qemu virtualbox бош и другие

    В KVM -- никак, KVM использует фичу хостового процессора известную как 2-stage translation, при этом на первой стадии хостовый процессор выполняет трансляцию гостевого виртуального адреса в гостевой физический, аппаратно.

    В QEMU -- я тебе уже писал как, с деталями и ссылочками в код. Но ты вместо того чтобы задавать конкретные вопросы опять начинаешь говорить что там всё сложно и непонятно.

    Какой там алгоритм замещения(Или его там нету).

    В QEMU собственный TLB QEMU прямого отображения, в случае промаха единственная запись TLB в которой может быть отображение для искомого виртуального адреса замещается новой трансляцией. Зависящий от эмулируемой архитектуры TLB эмулирует детали архитектуры, тебе нужно выбрать конкретную архитектуру чтобы её обсуждать, иначе мы закопаемся среди разных вариантов.

    void* translate(int acid, int addr){

    Похож на реализацию собственного TLB QEMU, только там нет ASID и в качестве тега используются все биты виртуального адреса кроме младших (обычно младших 12, но может быть меньше, если у эмулируемой архитектуры есть страницы меньшего размера).
    Ответ написан
    Комментировать
  • Как в архитектурах risc одинаковые виртуальные адреса разных контекстов задач различаются?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В risc вроде там куча csr регистров

    Вот на этом месте остановись. RISC -- это не конкретный набор инструкций и регистров, это принцип организации набора инструкций. RISC-процессоры все разные, возьми крнкретный и разбирайся с ним, не вали их все в одну кучу, не ставь на вопрос теги процессоров которые не имеют к нему отношения.

    на разных компиляторах одна си операция ассемблируется то в комбинацию lui + addi, то в комбинацию auipc +addi

    Ты указал ARM в тегах, но у ARM нет инструкций lui и auipc. Такие инструкции есть у RISC-V.
    Если ты посмотришь в The RISC-V Instruction Set Manual, раздел 2.4 Integer Computational Instructions, то увидишь, что опкод lui загружает константу собранную из 20 битов непосредственного значения из инструкции и 12 нулевых младших битов в целевой регистр, а auipc прибавляет такую же точно константу к PC и загружает в целевой регистр результат сложения, и в этом вся разница между ними.

    где какая используется не совсем понимаю.

    lui используется для генерации констант, которые не зависят от того, где расположен код, а auipc для генерации констант, которые двигаются вместе с кодом. Т.е. Если ты хочешь вызвать функцию, которая находится дальше чем ±2К от точки вызова, ты можешь сгенерировать её адрес инструкцией auipc, и полученный код будет работать одинаково, независимо от того, по какому адресу он будет размещён. А если тебе надо поместить в регистр константу, например 0x12345678, то ты можешь это сделать парой инструкций lui rd, 0x12345 ; addi rd, rd, 0x678 и значение константы будет всегда одинаковым, вне зависимости от того, где будет этот код.

    Каким образом одинаковые адреса различаются. Или они просто не могут быть одинаковыми(типа ос позаботиться)?

    Если есть MMU и он используется ОС, то есть и виртуальные адреса и они могут быть одинаковыми у разных процессов. Если MMU нет или он не используется, то ОС размещает все процессы в одном адресном пространстве, нет смысла говорить отдельно о виртуальных адресах, поскольку они равны физическим, адреса выделяемые ОС разным процессам могут быть как одинаковыми (например несколько процессов запущенных из одного исполняемого образа могут использовать один и тот же код и константные данные), так и разными (например изменяемые данные разные у всех процессов, а стеки разные у всех потоков).

    Как они в tlb обрабатываются, если вдруг они реально могут быть одинаковыми, и там нету ни каких дополнительных индексов процесса)

    Выбери конкретную процессорную архитектуру -- обсудим. у многих RISC-архитектур есть ASID, который идентифицирует адресное пространство и записывается вместе с виртуальным адресом в TLB. Но в любом случае ASID -- это просто оптимизация для повышения производительности, когда он отсутствует или переполняется ОС должна сбрасывать содержимое TLB при переключении адресного пространства.

    У ARM есть регистры TTBR с примерно той же функцией, что и cr3 в x86.
    У RISC-V есть CSR satp, содержащий ASID и базовый адрес корневого каталога страничных таблиц. Об этом можно прочитать в разделе 4.1.12 Supervisor Address Translation and Protection (satp) Register спецификации The RISC-V Instruction Set Manual Volume II: Privi....
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание больше чем двойное машинное слово? Директива p2align 4 и более?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему нужно 512-356 байт нулями заполнять, почему нельзя продолжить дальше. Ведь следующая после 86*4 байт инструкция(или переменная) будет выровнена

    А вот еслы бы ты тупо взял и прочитал документацию на директиву .p2align, то у тебя таких вопросов не было бы. Потому что никто не заполняет 512-356 байт после. .p21lign выравнивает текущий адрес по заданной степени двойки. Обычно для этого есть аппаратные причины, например базовый регистр таблицы векторов прерываний может иметь 9 младших бит зафиксированных в 0. Или вот по границе страницы MMU выравнивают данные в ELF-файлах, чтобы можно было установить отдельно разрешения RX для кода и констант и RW для изменяемых данных.

    для получения элемента допустим table[index_nBit] можно применять операцию ИЛИ вместо сложения. Что быстрее. В этом ли дело

    Нет, не в этом.
    Ответ написан
    1 комментарий
  • Почему компиляторы не используют инструкции повторения REP movs?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему компиляторы не используют инструкции повторения REP movs?

    чего это "не используют"? Используют.

    Она должна быть в миллиард раз быстрее

    Инструкция которую не нужно читать из памяти, но которая сама лезет в память дважды на каждом цикле своего выполнения не может быть "в миллиард раз быстрее" других реализаций той же логики.
    Ответ написан
    Комментировать
  • Получение доступа к регистру rip x86-64 архитектура?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как получить доступ к этому регистру?

    lea (%rip), %rax (в синтаксисе at&t) получает адрес следующей инструкции
    Ответ написан
    2 комментария
  • Возможно отключить не-которые инструкций процессора?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Возможно отключить некоторые инструкций процессора?

    На x86 с виртуализацией -- да, возможно. Но не для произвольных инструкций, а только для тех, для которых это предусмотрено разработчиками. А кроме того…

    отключить инструкций процессора отвечающий за скорость майнинга

    …для майнинга используются те же инструкции, что и для воспроизведения видео, и проигрывания музыки, и просто арифметики. Невозможно глядя на отдельно взятую инструкцию сказать: "ага, тут происходит майнинг".

    умеют ли программы виртуализации такое проворачивать?

    qemu например умеет ограничивать набор инструкций доступных внутри виртуальной машины управляя флагами CPUID, см.
    Ответ написан
  • Хочу написать простенький симулятор процессора для уроков, какую выбрать систему команд?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Какую систему команд выбрать? …
    для демонстрации принципов работы ассемблера

    Для этого нужно ответить на вопросы: где вы собираетесь взять ассемблер и как конкретно вы собираетесь демонстрировать его работу?
    Я вижу два возможных ответа на первый вопрос: взять готовый или написать самому. Если цель -- написать самому, то это может быть сравнимо по сложности, если не сложнее, чем написать эмулятор для той же самой системы команд. Если брать готовый, я бы рекомендовал RISC-архитектуру, но все они с теми или иными заморочками, так что это будет выбор наименьшего из зол. На мой взгляд RISC-V, точнее базовый набор RV32I -- достойный кандидат.
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание памяти? Точнее, почему процессор обращается 2 раза к невыравниным данным?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Для процессора x86 с word 32bit. Как будут выполняться fetch?
    Хочу ответ в таком формате.

    Что мешает взять спецификацию на процессор и почитать, например, раздел 5.3.6?

    почему процессор обращается 2 раза к невыравненным данным?

    Если посмотреть на схему i386 на первой же странице документа по ссылке выше, то можно увидеть, что шина адреса процессора имеет линии A2 - A31. Линий A0 и A1 тупо вообще нет, физически.
    Ответ написан
    Комментировать
  • Как в конвейерном 32bit процессоре передается команды записи в Reg 32 Битного значения??

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    А как передать-то 32 битное значение в команде в 32 бит?
    Логично что после команды значение(или адрес). Но тогда же получается какое-то нарушение логики.

    В RISC-процессорах -- никак. Они либо имеют команду загрузки 32-битного значения (литерала) из памяти относительно PC или специально выделенного регистра (например ARM: LDR r [pc, #offset_to_literal_pool], XTENSA: l32r at, label), при этом в команде кодируется смещение адреса литерала относительно PC. Либо загружают значения по частям, двумя или более командами (например MIPS загружает 16-битные части двумя разными инструкциями: lui rt, high16 ; ori rt, low16, XTENSA загружает 16-битные части двумя одинаковыми инструкциями: CONST16 at, high16 ; CONST16 at, low16, RISC-V загружает 20 и 12-битные части: auipc rd, symbol[31:12] ;addi rd, rd, symbol[11:0]).
    Хотя в принципе тот же RISC-V имеет нефиксированную длину команд, так, что какой-нибудь разработчик может завести, скажем, 6-байтовую команду загрузки 32-битного непосредственного значения в регистр, однако, насколько мне известно, никто этого не делает.
    Ответ написан
    Комментировать
  • Что такое Потоки на уровне ОС? В 1-ядерном процессоре же всего 1 поток?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    И К примеру выполняется такие команды, как пример инструкция чтения строки из stdin, почему вся ос не глохнет. Типа что в этот момент ожидания времени происходит, Или что ОС все 1000 потоков переключает там каждую 0.0001 секунды?

    Только готовые к выполнению потоки получают процессорное время. Потоки могут останавливаться в ожидании какого-либо примитива синхронизации, например семафора или мьютекса. Такие потоки не занимают процессор.
    Поток читающий из stdin может останавливаться, например, на семафоре, защищающем очередь данных stdin когда она пуста. Какой-то другой поток должен поместить новые данные в очередь stdin и открыть этот семафор, переведя ожидающий поток в состояние готовности к выполнению.
    Ответ написан
    Комментировать
  • Как посчитать кол-во обращений в разных типах кэшей?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    - кол-во обращений к кэшу, если кэш прямого отображения,
    - кол-во обращений к кэшу, если кэш полностью ассоциативный.
    Подскажите пожалуйста, как такое считается.

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

    Если массив int test[512]; занимает 2048 байт памяти (sizeof(int) == 4), тогда он полностью умещается в заданный кэш и разницы между кэшем прямого отображения и полностью ассоциативным не будет. Внутренний цикл обращается к элементам массива, лежащим в разных кэш-линиях (поскольку 16(шаг цикла) * sizeof(int) > 16(размер кэш-линии)). т.е. каждое обращение внутреннего цикла пойдёт в память на первой итерации внешнего цикла. На второй и последующих итерациях внешнего цикла все обращения из внутреннего цикла пойдут в кэш. Т.е. всего обращений в кэш будет 9 * (512 / 16).
    Ответ написан
    Комментировать
  • Как процессор распознает длину команды?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как процессор может отличить длину команды (1, 2, и 3 байт), чтобы выполнить следующую команду ?

    По коду операции -- части команды, которая кодирует действие команды. В процессоре закодировано соответствие кода операции и длины команды. Код операции может полностью содержаться в первом байте команды (как в 8080), либо может быть распределён между несколькими байтами команды. В последнем случае часть кода операции находящаяся в первом байте должна отличаться от кода операции любой однобайтовой команды чтобы их можно было отличить.

    Почему кроме команды Остановить все команды занимают 3 байта?

    Если речь о 8080, то это утверждение неверно. В 8080 есть несколько однобайтовых команд (nop, битовые сдвиги и вращения, push/pop, и т.д.), несколько двухбайтовых (mvi и арифметика с непосредственными значениями -- adi, aci, и т.д.) и несколько трёхбайтовых (команды с прямой адресацией -- lda, sta, и т.д., переходы, вызовы подпрограмм и т.д.). Потому что значения, с которыми оперируют команды находятся в байтах следующих за первым -- в одном, если нужен 1-байтовый операнд и в двух если нужен 2-байтовый операнд или адрес.

    Как происходить выборка команды? Как найти логическую схему выборки команды?

    Можно посмотреть в исходники отреверсированного 8080.
    Ответ написан
    Комментировать
  • Как реализовать на с или assembler асинхронную выборку из RAM?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как реализовать на с или assembler асинхронную выборку из RAM?

    Например так. Это часть реализации memcpy для MIPS. Этот код не выглядит асинхронным, но написан именно так (сначала групповая загрузка в разные регистры, потом изменение базового адреса загрузки, потом групповое сохранение, потом изменение базового адреса сохранения) с рассчётом на то, что процессор сможет, в том числе, перекрыть во времени операции загрузки, арифметики и сохранения данных.
    Ответ написан
    2 комментария
  • Какие книги подробно описывают устройство процессора?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Ответ написан
    Комментировать
  • Есть ли какие-нибудь паттерны или фрейворки для программирования под многоядерные ARMы?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Есть ли какие-нибудь ... технологии в языках, ориентированные на многоядерность?

    OpenMP.
    Ответ написан
    Комментировать
  • Как происходит выборка команды в процессоре?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Допустим, значение счетчика равно 0000, я должен записать байт 10h. Как я понял, команду нужно указать через пульта управления на RAM (слева). Например, указал 10h, то получается что во все 3 защелки записывается 10h (То есть 10h 10h 10h) ???

    Нет, не получается. Если значение счётчика равно 0000, то байт 10h ты запишешь только по адресу 0. А машина будет извлекать три байта по адресам 0000, 0001 и 0002 в защёлки:
    В нашем сумматоре каждая ко-
    манда занимает по 3 байта и извлекается из памяти побайто-
    во. Выборка одной команды занимает три цикла синхронизи-
    рующего сигнала, а полный командный цикл — четыре цикла
    синхронизирующего сигнала.


    А как записать команду 10h 00 00??

    Надо перейти к адресу 0001 и записать байт 00, затем к адресу 0002 и записать байт 00.
    В предыдущей главе написано, как можно программировать такую память.
    Ответ написан
    3 комментария
  • Как определить время выполнения адресации?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Задача в такой постановке не имеет решения и скорее всего не имеет смысла.
    Попробуй для начала ответить, время чего именно ты хочешь замерить.
    Я подозреваю, что ты хочешь сравнить скорость выполнения конкретной программы написанной с использованием того или иного метода адресации. Если это так, то это понятная задача, но не стоит называть её "определением времени выполнения адресации". Для её решения можно воспользоваться счётчиком тактов если он есть в твоём процессоре. Если нет -- можно воспользоваться внешним таймером.
    Ответ написан
    6 комментариев