473,396 Members | 2,085 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

How to enforce execution order?

Hi there,

i have a sequence like the following:

const char *a = "foo";
char b[10];

for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?

I work in a multithreaded environment, and Semaphores, Mutex etc. are
not suitable for the current situation.

-Sacha

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 31 '06 #1
14 3511

"Sacha Schär" <sa**********@unibas.ch> wrote in message
news:43**********@news.bluewin.ch...
Hi there,

i have a sequence like the following:

const char *a = "foo";
char b[10];

for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?


volatile const char *a = "foo";

BTW why are you using C-style strings instead of std::string?
-Mike
Jan 31 '06 #2
Sacha Schär wrote:
i have a sequence like the following:

const char *a = "foo";
char b[10];

for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?
Turn off optimizations for this particular piece of code. Consult with
your compiler manual on how to do that.
I work in a multithreaded environment, and Semaphores, Mutex etc. are
not suitable for the current situation.


And it's not relevant to the newsgroups you posted to, anyway. There are
no such things like "Semaphores" or "Mutex" in C++.

V
Jan 31 '06 #3
This is just a guess.. how about an inline function?

void inline copyFirstElem(const char *a, char *b)
{
b[0] = a[0]
}

{Please do not top post. -mod/fg}

Sacha Schär wrote:
Hi there,

i have a sequence like the following:

const char *a = "foo";
char b[10];

for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?

I work in a multithreaded environment, and Semaphores, Mutex etc. are
not suitable for the current situation.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #4
Sacha Schär wrote:
i have a sequence like the following:

const char *a = "foo";
char b[10];

for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped.
Sure, it can do whatever it wants, as far as the final effect is the same.
How can I enforce, that the copying of the char at
position 0 is done after the loop?
It does not make any difference. After all, you want to copy some bytes
somewhere, right?
I work in a multithreaded environment
So you don't want to *just* copy some bytes somewhere, you want to make
some more complicated logic on top of it.
If a and b are shared objects, then you have to use proper tools to make
the threads properly collaborate. It's not only about order, but also
about visibility.
and Semaphores, Mutex etc. are
not suitable for the current situation.


Why? Without proper synchronization tools, there is nothing you can do
to *enforce* any particular ordering of events in the multithreaded
application.
--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #5
Sacha Schär schrieb:
<snip>
for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?


switch off all optimizations?

to be honest, you'd have to fool the compiler's optimization by using
some value that could be computed only at the end of the loop i.e.

int i;
for ( i = 0 ; i < strlen(a); i++ )
{ b[i] = a[i]; }

// this is not portable at the moment
// i think there is a macro CHAR_BYTES that should replace the "8"
// and the mask must be fixed
b[0] = ((unsigned int)i<<8|(unsigned int)(a[0]))&0xff;

however, even with this the compiler might be clever enough to get it out.

the most secure way would be to reimplement the loop using assembler.

greetings from dresden
andré

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #6
On 2006-01-31 17:55, Sacha Schär wrote:
i have a sequence like the following:

const char *a = "foo";
char b[10];

for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?

I work in a multithreaded environment, and Semaphores, Mutex etc. are
not suitable for the current situation.


The reordering of accesses by the compiler can be prevented by
performing the relevant accesses through volatile-qualified lvalues.
But in a multithreaded environment this isn't good enough, because the
hardware can reorder accesses as well, in addition to the compiler.
To prevent such reordering at the hardware level, you need to issue
a memory barrier instruction, either directly or by employing some
synchronization primitive. How you can do this is compiler- and/or
OS-dependent.

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #7
Sacha Schär wrote:
i have a sequence like the following: const char *a = "foo";
char b[10]; for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0]; I guess, an optimizing compiler might mixup the execution
order of this code snipped. How can I enforce, that the
copying of the char at position 0 is done after the loop?
In what sense? The standard requires that the observable
behavior be as if the assignment at position 0 occured after the
loop. But since there is no observable behavior in the above, a
compiler can pretty much do what it wants. Because there is no
observable behavior, of course, you can't tell what it does,
either.
I work in a multithreaded environment, and Semaphores, Mutex
etc. are not suitable for the current situation.


If other threads can access b, then you cannot avoid some sort
of synchronization primitive. Posix offers mutex, and a few
others; Windows, and many Unix platforms, also have lower level
primitives. But without some primitive, there is no guarantee
concerning the order of the writes as seen in another thread.
(And it's not just a problem of the compiler. Modern hardware
does considerable reordering itself. The primitives will use
special hardware instructions to inhibit the reordering. And
typically, there is no way to get the compiler to emit these
instructions; it must be done in assembler.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #8
Sacha Schär wrote:
const char *a = "foo";
char b[10];
for ( i = 1; i < strlen(a); i++)
b[i] = a[i];
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped. Yes, as long as the observable behaviour does not change.
How can I enforce, that the copying of the char at
position 0 is done after the loop? Make 'b' volatile "volatile char b[10]".
I work in a multithreaded environment, and Semaphores, Mutex etc. are
not suitable for the current situation.

You should also consider CPU cache coherency. For example, another thread may run on
another CPU and it's cache may contain different values in 'b' than the cache of the CPU
running your main thread. You may also need a memory barrier here.

It would help you you explained the problem you are trying to solve.

Also, it is not efficient to call strlen in each iteration, it would be a way faster to
calculate it once and use that value (although sometimes a good compiler may be able to
optimise that call away if it can prove that 'a' and 'b' do not overlap).

--

Valentin Samko - http://www.valentinsamko.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #9

"Sacha Schär" <sa**********@unibas.ch> skrev i meddelandet
news:43**********@news.bluewin.ch...
Hi there,

i have a sequence like the following:

const char *a = "foo";
char b[10];

for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of
this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?


Why would you?

An optimizing compiler can do anything it likes, as long as you can't
tell the difference. That is called the "as-if" rule. The code must be
executed as-if it is done exactly in the order you write it.

Can you tell the difference?
Bo Persson


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #10
Sacha Schär wrote:
I guess, an optimizing compiler might mixup the execution order of this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?
Put it in an _asm block.
Or put an empty _asm block between the loop and the last line.
Or turn off optimization.

Or, document the problem and report it to the compiler...
if you can tell the difference in a conforming program, then the
compiler is broken.
I work in a multithreaded environment, and Semaphores, Mutex etc. are
not suitable for the current situation.


In a multithreaded environment, strike the bit about a conforming
program,
because the standard doesn't currently address multiple threads.
But still, if the semaphore or whatever works properly, it ought to
guard the order of your program's execution.
Check your compiler's documentation!
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #11
Sacha Schär <sa**********@unibas.ch> wrote:
i have a sequence like the following:

const char *a = "foo";
char b[10];

for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0];

I guess, an optimizing compiler might mixup the execution order of this
code snipped. How can I enforce, that the copying of the char at
position 0 is done after the loop?


Why do you need this? It might not be enough to ensure that "b[0] =
a[0]" happens at the end since the compiler might not even write the
data to memory but keep it in registers up to a point.

You can use a compiler barrier before the last assignment (and maybe
one more after it if you want to ensure that the data was really
written to memory). In general, any function call (which is not
inlined) is a compiler barrier. Otherwise, it depends on the
compiler. For gcc, an empty asm directive would do the job:

asm volatile ("" : : : "memory");

It might help if you detail the problem you are seeing a bit more.

--
Catalin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 1 '06 #12
André Kempe wrote:
Sacha Schär schrieb:
<snip>
for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0]; I guess, an optimizing compiler might mixup the execution
order of this code snipped. How can I enforce, that the
copying of the char at position 0 is done after the loop?
switch off all optimizations?
[...] the most secure way would be to reimplement the loop using
assembler.


Note that even then, unless you use special instructions to
ensure otherwise, another thread may see the writes in a
different order.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 2 '06 #13
Catalin Marinas wrote:
Sacha Schär <sa**********@unibas.ch> wrote:
i have a sequence like the following: const char *a = "foo";
char b[10]; for ( i = 1; i < strlen(a); i++)
{
b[i] = a[i];
}
b[0] = a[0]; I guess, an optimizing compiler might mixup the execution
order of this code snipped. How can I enforce, that the
copying of the char at position 0 is done after the loop?
Why do you need this? It might not be enough to ensure that
"b[0] = a[0]" happens at the end since the compiler might not
even write the data to memory but keep it in registers up to a
point. You can use a compiler barrier before the last assignment (and
maybe one more after it if you want to ensure that the data
was really written to memory). In general, any function call
(which is not inlined) is a compiler barrier. Otherwise, it
depends on the compiler. For gcc, an empty asm directive would
do the job: asm volatile ("" : : : "memory");


Not on a Sparc. You'd have to put a membar instruction in the
asm directive.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 2 '06 #14
"kanze" <ka***@gabi-soft.fr> wrote:
Catalin Marinas wrote:
You can use a compiler barrier before the last assignment (and
maybe one more after it if you want to ensure that the data
was really written to memory). In general, any function call
(which is not inlined) is a compiler barrier. Otherwise, it
depends on the compiler. For gcc, an empty asm directive would
do the job:

asm volatile ("" : : : "memory");


Not on a Sparc. You'd have to put a membar instruction in the
asm directive.


I was only talking about the compiler barrier, not the hardware
one. If you are not on an SMP system or the memory location doesn't
need to be accessed by something other than the CPU itself, an empty
asm instruction is enough. This is because even if the value didn't
get to memory (weakly ordered memory or write buffers), the CPU should
be smart enough to get it from the write buffers if it is read by
itself. The only use of this is probably for the code that breaks the
strict aliasing rules.

On SMP or if the location is shared with a device, indeed you would
need a hardware memory barrier as well (and maybe cache flushing). My
experience is mainly with ARM processors but I don't think it is too
different on Sparc (I might be wrong though).

--
Catalin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Feb 2 '06 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: z. f. | last post by:
Hi, i have a class that is derived from System.Web.UI.Page, and this is the class i use in my application as PageBase. all other page classes are deriverd from my PageBase instead of the...
8
by: Frank van Vugt | last post by:
Hi, If during a transaction a number of deferred triggers are fired, what will be their execution order upon the commit? Will they be executed in order of firing or alfabetically or...
23
by: roman | last post by:
Hi, I would like to have two actions for one event. But I want the second action to trigger when the first one action completes. Is it possible to do this in javascript? I'm using the onclick...
42
by: Sabiyur | last post by:
Hi all, one of the recent post gives the macro to do swap #define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp) This macro will work, if the execution is from left to right. That is step 1)...
36
by: dspfun | last post by:
Hi! Is there any way in C that one can guarantee that instructions are executed in the same order as they are written in the program? For example, say I have the following: instruction1;...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.