Memory Barrier: Difference between revisions
Yuron [PHRhYmxlIGNsYXNzPSJ0d3BvcHVwIj48dHI+PHRkIGNsYXNzPSJ0d3BvcHVwLWVudHJ5dGl0bGUiPkdyb3Vwczo8L3RkPjx0ZD51c2VyPGJyIC8+YnVyZWF1Y3JhdDxiciAvPmludGVyZmFjZS1hZG1pbjxiciAvPnN5c29wPGJyIC8+PC90ZD48L3RyPjwvdGFibGU+] (talk | contribs) m (1 revision imported) |
pc>Yuron No edit summary |
||
Line 1: | Line 1: | ||
{{#set: Priority=2 | Summary=Enforcing the <i>ordering</i> of operations on the address space.}}<!-- | {{#set: Priority=2 | Summary=Enforcing the <i>ordering</i> of operations on the address space.}}<!-- | ||
-->{{#invoke:Dependencies|add|Synchronisation,3|Write Buffer,3}} | -->{{#invoke:Dependencies|add|Synchronisation,3|Write Buffer,3}} | ||
The details here could get a bit complex, so this is only a sketch. | The details here could get a bit complex, so this is only a sketch. Both the term “memory barrier” and some applications of | ||
Both the term “memory barrier” and some applications of | the mechanism are liable to crop up in a study of operating systems though. | ||
the mechanism are liable to crop up in a study of operating systems | |||
though. | |||
Modern computer processors can have very complex behaviour. The | Modern computer processors can have very complex behaviour. The hardware may try to do all sorts of ‘behind the scenes’ | ||
hardware may try to do all sorts of ‘behind the scenes’ | |||
optimisations; most of the time the programmer need not care. | optimisations; most of the time the programmer need not care. | ||
<blockquote> | <blockquote> | ||
An example: memory (in general) is often a bottleneck. A memory | An example: memory (in general) is often a bottleneck. A memory write (‘store’) operation may therefore be <strong>buffered</strong> as a fire-and-forget operation; it is committed and will get done but the processor doesn’t have to wait. Let’s follow that with a memory read (‘load’): the processor may <em>reorder</em> the operations so that the read (which is fetching data wanted <em>now</em>) overtakes the write. | ||
write (‘store’) operation may therefore be <strong>buffered</strong> | |||
as a fire-and-forget operation; it is committed and will get done | |||
but the processor doesn’t have to wait. Let’s follow that with a | |||
memory read (‘load’): the processor may <em>reorder</em> the | |||
operations so that the read (which is fetching data wanted <em>now</em>) | |||
overtakes the write. | |||
The first danger would be reading back the written (but not yet!) | The first danger would be reading back the written (but not yet!) location; good thinking, but don’t worry – the hardware is smart enough to spot that and <em>forward</em> the queued value. | ||
location; good thinking, but don’t worry – the hardware is smart | |||
enough to spot that and <em>forward</em> the queued value. | |||
However, imagine the write is to a [[Peripheral devices|peripheral device]] | However, imagine the write is to a [[Peripheral devices|peripheral device]] to start an operation and the read is to see if the operation is complete by testing if the device is ‘still’ busy. The addresses used are probably different; the hardware isn’t going to recognise the problem, the answer is going to be ‘not busy’ but because the operation hasn’t started, not because it | ||
to start an operation and the read is to see if the operation is | |||
complete by testing if the device is ‘still’ busy. The | |||
addresses used are probably different; the hardware isn’t going to | |||
recognise the problem, the answer is going to be ‘not | |||
busy’ but because the operation hasn’t started, not because it | |||
is complete. Disaster! | is complete. Disaster! | ||
(This is a bit of a contrived example: the above problem would | (This is a bit of a contrived example: the above problem would normally be solved by marking the address space containing the | ||
normally be solved by marking the address space containing the | device as “unbufferable”. However it is quite a simple example.) | ||
device as “unbufferable”. However it is quite a simple | |||
example.) | |||
</blockquote> | </blockquote> | ||
A memory barrier (sometimes called a “<strong>fence</strong>”) is an | A memory barrier (sometimes called a “<strong>fence</strong>”) is an instruction which causes all memory operations before it to be complete before starting operations after it. The programmer can then be <em>sure</em> something has happened. Memory barriers provide a mechanism for the [[synchronisation]] of the operations <em>within</em> a particular thread. | ||
instruction which causes all memory operations before it to be | |||
complete before starting operations after it. The programmer can then | |||
be <em>sure</em> something has happened. Memory barriers provide a mechanism | |||
for the [[synchronisation]] of the operations <em>within</em> | |||
a particular thread. | |||
Memory barriers can be useful when multiple processors communicate | Memory barriers can be useful when multiple processors communicate through ordinary RAM, for example. | ||
through ordinary RAM, for example. | |||
<blockquote> | <blockquote> | ||
Exercise: go and find (or think of) a better (e.g. a multiprocessor) | Exercise: go and find (or think of) a better (e.g. a multiprocessor) example of using a memory barrier. | ||
example of using a memory barrier. | |||
</blockquote> | </blockquote> | ||
---- | ---- | ||
{{BookChapter|6.4.1|265-266}} | |||
{{PageGraph}} | {{PageGraph}} | ||
{{Category|Memory}} | {{Category|Memory}} |
Revision as of 13:11, 2 August 2019
Depends on | Synchronisation • Write Buffer |
---|
The details here could get a bit complex, so this is only a sketch. Both the term “memory barrier” and some applications of the mechanism are liable to crop up in a study of operating systems though.
Modern computer processors can have very complex behaviour. The hardware may try to do all sorts of ‘behind the scenes’ optimisations; most of the time the programmer need not care.
An example: memory (in general) is often a bottleneck. A memory write (‘store’) operation may therefore be buffered as a fire-and-forget operation; it is committed and will get done but the processor doesn’t have to wait. Let’s follow that with a memory read (‘load’): the processor may reorder the operations so that the read (which is fetching data wanted now) overtakes the write. The first danger would be reading back the written (but not yet!) location; good thinking, but don’t worry – the hardware is smart enough to spot that and forward the queued value. However, imagine the write is to a peripheral device to start an operation and the read is to see if the operation is complete by testing if the device is ‘still’ busy. The addresses used are probably different; the hardware isn’t going to recognise the problem, the answer is going to be ‘not busy’ but because the operation hasn’t started, not because it is complete. Disaster! (This is a bit of a contrived example: the above problem would normally be solved by marking the address space containing the device as “unbufferable”. However it is quite a simple example.)
A memory barrier (sometimes called a “fence”) is an instruction which causes all memory operations before it to be complete before starting operations after it. The programmer can then be sure something has happened. Memory barriers provide a mechanism for the synchronisation of the operations within a particular thread.
Memory barriers can be useful when multiple processors communicate through ordinary RAM, for example.
Exercise: go and find (or think of) a better (e.g. a multiprocessor) example of using a memory barrier.
Also refer to: | Operating System Concepts, 10th Edition: Chapter 6.4.1, pages 265-266 |
---|