что такое out of order execution

OOX 2.0: Out of order execution made easy

As Intel’s Threading Building Blocks (TBB) library is being refreshed using the new C++ standard, deprecating tbb::task interface, the need for a high-level tasking interface becomes more obvious. In this article, I’m proposing another way of defining how a high-level parallel task programming model can look like in modern C++. I created it in 2014 as my last contribution to TBB project as a core developer after 9 wonderful years of working there. However, this proposal has not been used in production yet, so a new discussion might help it to be finally adopted.

Motivation

According to customer feedback, the nested blocking programming model used in TBB can cause deadlocks if a program uses parallel algorithms with locks in user functions. It can be worked-around using tbb::task_arena by preventing work mixing but it is not an efficient approach. And there is no good way to solve the latency problem: one outermost task can get stuck until another outermost task of a high-level algorithm completes. It can be approached in different ways, e.g. using stack-switching (co-routines), just replacing a blocked thread by a new one, or preventing the task stealing using tbb::this_task_arena::isolate(). This article explores a purely semantical way out of these issues. It avoids the burden of additional restrictions, complexity, or resources in the scheduler since at low-level, it is all still possible via the deprecated tbb::task interface.

Design forces

Main idea

A solution for the nested blocking issue requires interrupting the current execution scope either by switching to a new stack/thread (scheduler way) or by terminating and splitting the scope into parts running as a sequence of continuations (semantical way). The latter leads to additional complexity of dealing with variables which go out of scope, e.g. consider this example with blocking style:

If we want parallel_reduce not to block, we need to split this into two tasks (by lines) with separate scopes. But how to deal with the `result` then? The concept of `future` seems to be the closest approach to this and C++11 provides std::async(), which returns std::future as a result of the user’s functor:

Now, how to connect the tasks into as a sequence? std::future is blocking. However, this example demonstrates that the most native way to express dependencies is to follow the function arguments: the second task waits for the result of the first one. We just need to extend ideas of std::future and std::async to cover our needs.

Meanwhile, let’s consider the weakness of C++11 async constructs using the following example:

In order to support recursions like this for continuation-style tasking, we need to:
— directly initialize a ‘future’ variable by a value (optionally)
— collapse template recursion of a ‘future’ variables
— build task dependencies based on ‘future’ arguments instead of blocking
— unpack ‘future’ types into plain types before calling user functor

The result can be as beautiful and concise as the following:

All these requires tasking with multi-continuations and dynamic dependencies just as in the initial OOX (Out of Order eXecution) proposal by Arch Robison. Thus the `oox_` prefix and the second version. [Update 24-Sep-21] Now, OOX officially stands for Out-of-Order Executor.

Static Dependencies

OOX implementation enables automatic deduction for write-after-write («output»), write-after-read («anti»), and read-after-write («flow») dependencies. This new interface approach provides a way to enumerate all the prerequisites in arguments and identify their properties such as:

Thus, each oox_run task knows which oox_var can be modified, which has only to be read, and which can be just copied thus unlocking more potential parallelism with write-after-read dependent tasks. It allows building a complete task dependency graph without additional specifications beyond the oox_run() arguments for the case of a fixed number of tasks since the number of arguments is a compile-time decision:

что такое out of order execution. image loader. что такое out of order execution фото. что такое out of order execution-image loader. картинка что такое out of order execution. картинка image loader. As Intel's Threading Building Blocks (TBB) library is being refreshed using the new C++ standard, deprecating tbb::task interface, the need for a high-level tasking interface becomes more obvious. In this article, I’m proposing another way of defining how a high-level parallel task programming model can look like in modern C++. I created it in 2014 as my last contribution to TBB project as a core developer after 9 wonderful years of working there. However, this proposal has not been used in production yet, so a new discussion might help it to be finally adopted.

To sum up, there are two big design ideas behind OOX 2.0:
1. Abstract user functor from task dependencies
2. Reuse functor argument types for task dependency types specification
Users make their best effort to specify the minimally necessary access types and OOX extracts as much parallelism as possible in response.

Function and arguments types match

There are two options for passing arguments to oox_run and receiving them in the user functor.

Match oox_run arguments to functor arguments. It means if the functor receives by lv-reference, it will be stored as a reference and it will be the user’s responsibility for the lifetime of the referred object. However, if the functor receives by const-reference, a choice must be made: to copy the argument or to keep as a reference. If passed to oox_run as rv-reference, it must be a copy.

The standard uses a different way. You can choose to pass by reference and take responsibility for the object over its lifetime, but it has to be done explicitly via std::ref(), std::cref(), and std::reference_wrapper<>. Otherwise everything is passed by a value.

Since the semantics of oox_run arises from similarity with std::async and std::thread, it looks natural to assume the same rules for argument passing in case they are not oox_var, i.e. cplusplus.com says the following:

Their types shall be move-constructible. If Fn is a member pointer, the first argument shall be an object for which that member is defined (or a reference, or a pointer to it). The function uses decay copies of these arguments. Fn and Args. are template parameters: if implicitly deduced, these are the proper lvalue or rvalue reference types of the arguments. Note though, that the function uses decay copies of fn and args. (see std::ref for a wrapper class that makes references copyable).

Now, what to do with oox_var<> arguments? They differ from plain types because they guarantee lifetime and access synchronization. Following the same logic of unification and taking into account that access to oox_var<> content is synchronized by the dependency graph build by oox_run(), we can claim that arguments referred as oox_var<> are always stored by reference. It does not make much sense to always store arguments by value, since it kills half of use cases where oox_var<> is used as a synchronization point when a writer waits for readers. On the other hand, when a user functor takes an argument by value, it is not visible to the user whether a task stores it by value or by reference to the oox_var storage. The former enables task graph optimization opportunity when the producer can copy the argument to the consumer task and proceed to the next write immediately, without depending upon finishing of the consumer task. See note //1 below.

But when an oox_var argument is stored and passed by lv-reference, a visible difference with a plain type can arise for oox_var<> passed by r-value reference: oox_run(f, move(my_var)); It can prevent the optimization for functors f(T) and f(T&&) which works fine for non-oox types. Thus, arguments passed as oox_var&& have to be moved into the user functor instead of just passing as lv-reference as for other cases. See note //2 below.

The following table summarizes the observations above and couples it with dependency arcs types formed for the task graph as explained below (please note that this complexity is for the implementation writer rather than the user):

Источник

СОДЕРЖАНИЕ

История

Основная концепция

Чтобы оценить выполнение OoO Execution, полезно сначала описать по порядку, чтобы иметь возможность сравнить их. Инструкции не могут быть выполнены мгновенно: они требуют времени (несколько циклов). Следовательно, результаты будут отставать от того, где они необходимы. По-прежнему необходимо отслеживать зависимости. Однако его подход довольно прост: каждый раз заглохнуть. OoO использует гораздо более сложные методы отслеживания данных, как показано ниже.

Заказанные процессоры

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

Часто упорядоченный процессор имеет простой «битовый вектор», в который он записывается, который регистрирует конвейер, в который он (в конечном итоге) будет записывать. Если какой-либо из входных операндов имеет соответствующий бит, установленный в этом векторе, инструкция останавливается. По сути, вектор выполняет значительно упрощенную роль защиты от опасностей регистров. Таким образом, мы наблюдаем, что Out-of-Order использует 2D-матрицы, где In-order использует 1D-вектор для предотвращения опасности.

Вышедшие из строя процессоры

Эта новая парадигма разбивает обработку инструкций на следующие этапы:

Ключевая концепция обработки OoOE состоит в том, чтобы позволить процессору избежать определенного класса остановок, которые возникают, когда данные, необходимые для выполнения операции, недоступны. В схеме выше процессор OoOE избегает остановки, которая происходит на этапе (2) обработчика очередности, когда инструкция не полностью готова к обработке из-за отсутствия данных.

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

Разделение отправки и выпуска позволяет выпускать вне очереди

Буфер предназначен для разделения доступа к памяти и выполнения функций в компьютерной программе, а также для достижения высокой производительности за счет использования мелкозернистого параллелизма между ними. При этом он эффективно скрывает все задержки памяти с точки зрения процессора.

Разделение выполнения и обратной записи позволяет перезапустить программу

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

Источник

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

Внеочередное исполнение (Операционные Системы)

Содержание

История

что такое out of order execution. Atom. что такое out of order execution фото. что такое out of order execution-Atom. картинка что такое out of order execution. картинка Atom. As Intel's Threading Building Blocks (TBB) library is being refreshed using the new C++ standard, deprecating tbb::task interface, the need for a high-level tasking interface becomes more obvious. In this article, I’m proposing another way of defining how a high-level parallel task programming model can look like in modern C++. I created it in 2014 as my last contribution to TBB project as a core developer after 9 wonderful years of working there. However, this proposal has not been used in production yet, so a new discussion might help it to be finally adopted.

Первый суперскалярный процессор, поддерживающий внеочередное выполнение инструкций, был разработан Сеймуром Креем еще в 60-х годах XX века. Компания Intel выпустила свой первый суперскалярный процессор с внеочердным выполнением инструкций в 1995 году (Intel Pentium Pro), а компания AMD — в 1996-м (K5). С тех пор все процессоры Intel и AMD были суперскалярными с внеочередным выполнением команд. Все, но только не процессор Intel Atom, который был разработан компанией Intel в 2007 году для весьма специфического сегмента рынка. Он имеет суперскалярную архитектуру, но без возможности переупорядочения команд. Компания Intel не предусмотрела в этом процессоре такой функциональности, хотя возможность переупорядочения команд позволяет существенно повысить производительность процессора. Причина в том, что Intel Atom изначально разрабатывался как недорогой процессор с очень низким энергопотреблением для специфического класса устройств. Сразу предполагалось, что процессором Intel Atom будут оснащаться устройства выхода в Интернет, и не более того. Понятно, что для обеспечения выхода в Сеть высокая производительность процессора не нужна, а потому не было смысла наделять процессор Intel Atom дополнительной логикой внеочередного выполнения команд. Наличие логики Out-of-Order сделало бы процессор Intel Atom, во-первых, более дорогим, во-вторых, существенно увеличило бы его энергопотребление, в­-третьих, повысило бы размер кристалла, а в­четвертых, процессор обладал бы избыточной производительностью. В то время, когда разрабатывался процессор Intel Atom, отказ от использования блока Out-of-Order был самым эффективным способом существенно уменьшить энергопотребление процессора, а сверхнизкое энергопотребление и есть главная отличительная черта Intel Atom.

Объяснение процессов внеочередного исполнения

Подсистему внеочередного исполнения операций вместе с функциональными устройствами объединяют под названием «Back End», чтобы подчеркнуть её обособленность и самостоятельность. Внутри этой подсистемы обработка операций ведётся асинхронно, с учётом зависимостей между ними, готовности операндов и наличия требуемых ресурсов (устройств и очередей). При внеочередной обработке операций в этой подсистеме гарантируется, что результаты такого выполнения программы совпадут с результатами «правильного» последовательно выполнения.

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

In-Order vs. Out-of-Order

Выполнение инструкций по порядку (In-order)

Выполнение не по порядку (Out-of-order):

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

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

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

AMD vs. Intel

Сегодня концепция использования интернет-устройств на базе процессоров Intel Atom несколько изменилась. Фактически из устройств выхода в Интернет с минимальной функциональностью эти устройства трансформировались в устройства потребления контента. В связи с этим теперь наблюдается явный дефицит производительности процессоров Intel Atom. Частично проблему недостаточной производительности компания Intel решила за счет перехода от одноядерных к двухъядерным моделям процессоров Intel Atom, однако понятно, что это лишь попытка залатать дыры, так как без кардинального пересмотра микроархитектуры процессора проблему дефицита его производительности решить нельзя. На фоне явного дефицита процессора Intel Atom появлась конкурентная суперскалярной микроархитектура AMD Bobcat с внеочередным выполнением команд.

Источник

out-of-order execution

выполнение команд с изменением очередности
Способ исполнения программы, при котором передача команд осуществляется в порядке, отличном от указанного в программе.
[Л.М. Невдяев. Телекоммуникационные технологии. Англо-русский толковый словарь-справочник. Под редакцией Ю.М. Горностаева. Москва, 2002]

Тематики

Смотреть что такое «out-of-order execution» в других словарях:

Out-of-order execution — (in etwa: Außer der Reihe Ausführung) bezeichnet die Möglichkeit, Befehle in den Ausführungseinheiten eines (meist) superskalaren Prozessors außerhalb der Programmreihenfolge auszuführen, mit dem Ziel, die Pipelines möglichst gut auszulasten.… … Deutsch Wikipedia

Out-of-order execution — In computer engineering, out of order execution (OoOE or OOE) is a paradigm used in most high performance microprocessors to make use of instruction cycles that would otherwise be wasted by a certain type of costly delay. In this paradigm, a… … Wikipedia

Out-of-Order-Execution — Dieser Artikel oder Abschnitt ist nicht hinreichend mit Belegen (Literatur, Webseiten oder Einzelnachweisen) versehen. Die fraglichen Angaben werden daher möglicherweise demnächst gelöscht. Hilf Wikipedia, indem du die Angaben recherchierst und… … Deutsch Wikipedia

Out of Order — may refer to: Out of Order (novel), a novel by Phoebe Atwood Taylor Out of Order (Nuclear Assault album) Out of Order (Rod Stewart album) Out of Order (TV series), a miniseries starring Eric Stoltz and Felicity Huffman Out of Order (Curious… … Wikipedia

Out-of-order — Dieser Artikel oder Abschnitt ist nicht hinreichend mit Belegen (Literatur, Webseiten oder Einzelnachweisen) versehen. Die fraglichen Angaben werden daher möglicherweise demnächst gelöscht. Hilf Wikipedia, indem du die Angaben recherchierst und… … Deutsch Wikipedia

Exécution out-of-order — L exécution out of order (« dans le désordre » en anglais) d instructions par un processeur consiste à réorganiser l ordre dans lequel les instructions d un programme vont s exécuter. Ces instructions ne sont alors pas forcément… … Wikipédia en Français

In-Order Execution — (in etwa: in der Reihe Ausführung) bezeichnet die Beschränkung Befehle nur strikt nach Programmreihenfolge abarbeiten zu können. Im Gegensatz zur Out of order Execution, wo Befehle in den Ausführungseinheiten eines (meist) superskalaren… … Deutsch Wikipedia

order — or·der 1 n 1: a state of peace, freedom from unruly behavior, and respect for law and proper authority maintain law and order 2: an established mode or state of procedure a call to order 3 a: a mandate from a superior authority see also … Law dictionary

order — <>I.<> noun 1 way in which people/things are arranged ADJECTIVE ▪ correct, proper, right ▪ wrong ▪ logical ▪ The paragraphs are not in a logical order … Collocations dictionary

Exécution spéculative — En informatique, L exécution spéculative correspond au lancement anticipé d une instruction, c est à dire sans être certain que celle ci ait réellement besoin d être exécutée. Types Généralement, on peut distinguer trois type d instructions et de … Wikipédia en Français

out of commission — Commission Com*mis sion, n. [F., fr. L. commissio. See .] 1. The act of committing, doing, or performing; the act of perpetrating. [1913 Webster] Every commission of sin introduces into the soul a certain degree of hardness. South. [1913… … The Collaborative International Dictionary of English

Источник

СОДЕРЖАНИЕ

История

Основная концепция

Чтобы оценить выполнение OoO Execution, полезно сначала описать по порядку, чтобы иметь возможность сравнить их. Инструкции не могут быть выполнены мгновенно: они требуют времени (несколько циклов). Следовательно, результаты будут отставать от того, где они необходимы. По-прежнему необходимо отслеживать зависимости. Однако его подход довольно прост: каждый раз заглохнуть. OoO использует гораздо более сложные методы отслеживания данных, как показано ниже.

Заказанные процессоры

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

Часто упорядоченный процессор имеет простой «битовый вектор», в который он записывается, который регистрирует конвейер, в который он (в конечном итоге) будет записывать. Если какой-либо из входных операндов имеет соответствующий бит, установленный в этом векторе, инструкция останавливается. По сути, вектор выполняет значительно упрощенную роль защиты от опасностей регистров. Таким образом, мы наблюдаем, что Out-of-Order использует 2D-матрицы, где In-order использует 1D-вектор для предотвращения опасности.

Вышедшие из строя процессоры

Эта новая парадигма разбивает обработку инструкций на следующие этапы:

Ключевая концепция обработки OoOE состоит в том, чтобы позволить процессору избежать определенного класса остановок, которые возникают, когда данные, необходимые для выполнения операции, недоступны. В схеме выше процессор OoOE избегает остановки, которая происходит на этапе (2) обработчика очередности, когда инструкция не полностью готова к обработке из-за отсутствия данных.

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

Разделение отправки и выпуска позволяет выпускать вне очереди

Буфер предназначен для разделения доступа к памяти и выполнения функций в компьютерной программе, а также для достижения высокой производительности за счет использования мелкозернистого параллелизма между ними. При этом он эффективно скрывает все задержки памяти с точки зрения процессора.

Разделение выполнения и обратной записи позволяет перезапустить программу

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *