|
Thanks for your great reply peterchen,
I do not agree how compiler optimize the loop is correct. For example,
while(Sentinel==0)
Sleep(0);
I think the way compiler optimizes the while loop (or other similar loop) is based on the *fact* that the control condition of a loop will not be changed by another thread -- this *fact* is incorrect.
The common way in engineering to design whether or not a thread needs to be terminated is to let the thread in a loop and continues to check a bool variable called stopped. Actually, I do not see many people add volatile keyword to the stopped bool variable.
Any comments?
have a good weekend,
George
|
|
|
|
|
George_George wrote: Actually, I do not see many people add volatile keyword to the stopped bool variable.
You've come very far in what seems a short time, George
Maybe I should distinguish two things here: From what you (and I) would like to have, the compiler is doing something wrong, agreed. But from the view of the language definition, the compiler is absolutely correct.
My point of this post: The compiler cannot help you as much as you now think it could.
There are several reasons:
Holding frequently used values in a register is very important for optimizations - otherwise the compiler could generate neither fast nor compact code.
If the compiler would blindly assume that "some thread may modify values", the following variables could nopt be held in registers:
* all variables not declared in the local function block
* all variables of which a reference / addres is passed to some function
That would pretty much kill many optimizations that are essential to efficient object-oriented code.
Furthermore, all access to these variables would require to force synchronization between core caches, pretty much killing the advantage of multiple cores.
So you can either opt for the compiler to make things easy for you, or the compiler giving you full control. C++ almost always opts for "full control, but you need to know what you are doing". (That's why C++ is usually compared to a ferrari)
Keep in mind that, even above loop can be exited legally. Sleep(0) might throw an exception when it is finished. It might terminate the program using exit(). Generally, the compiler doesn't know the source code of Sleep.
It isn't as bad as you think. You can split data access from separate threads into the following two cases:
access to complex data
that's most structs and classes. In this case, you need to use a lock (e.g. CRITICAL_SECTION, or Mutex) anyway, since the access to these is not atomic. Acquiring/Releasing the lock takes care of the ugly stuff that would be caused by multiple threads.
Note that the compiler - even if it were aware of threads - couldn't help you with ANYTHING in that case.
atomic reads & writes
that's usually byte-, word- or integer- sized access, when they are well-aligned. The Sentinel example falls into that category.
In this case, the lock is not strictly necessary. BUT we now have to handle all the processor and memory issues involved with multithreading.
For this case, C++ offers volatile , which is a bit of a crutch. Additionally, the Win32 API offers Interlocked routines that allow safe access to a well aligned 32 bit integer. When linked correctly, this emits minimal assembly instructions. Using Interlocked, the sample could be fixed like this:
replace Sentinel = n with InterlockedExchange(&Sentinel, n)
replace Sentinel++ with InterlockedIncrement(&Sentinel);
replace reading Sentinel with InterlockedExchangeAdd(&Sentinel, 0)
On 64 bit systems, you also have 64 bit Interlocked functions, as well as finer-controlled routines
Phew.
|
|
|
|
|
Great post, Phew!
I agree with all of your comments. Except two more points,
1.
About Sleep(0), you mentioned there may be exceptions thrown in Sleep function. But from MSDN, I can not find, could you kindly point it out please?
http://msdn2.microsoft.com/en-us/library/ms686298(VS.85).aspx[^]
peterchen wrote: Sleep(0) might throw an exception when it is finished.
2. About the purpose of volatile
From MSDN, it is not formally mentioned that volatile will ensure the atomic operation -- only used to prevent compiler from optimization. If I missed any information, please feel free to correct me.
peterchen wrote: For this case, C++ offers volatile, which is a bit of a crutch
regards,
George
|
|
|
|
|
1.) The compiler doesn#t rea the MSDN
All it knows is that it is imported from an Kernel32.dll with a given signature. The funciton could do anything. You could have designed it to e.g. poll for a file, and when it's gone it throws. (And that's exactly what MUST happen if the DLL is replaced with one that does this.)
(Point of above post: even if the compiler had special built-in knowledge about Sleep(), it couldn't help you in all the cases where ).
2.) Maybe I wasn't clear with this.
Of course, volatile doesn't affect atomicity.
A memory read/write is atomic if it byte, word, DWORD (or QWORD on 64 bit) and is aligned on an address a multiple of its size. Then, the value is read or written in a single cycle, and no other thread or core could possibly interrupt.
However, all caching problems still remain: either caching in a register (by the optimizer), or caching in the CPU. volatile helps with these (but would be mostly useless with non-atomic accesses anyway).
|
|
|
|
|
Thanks peterchen,
I learned a lot from you. Let us come to the conclusion directly, what are your best practices when we need to use volatile and when not to use.
regards,
George
|
|
|
|
|
Heh
Different opinions exist.
While I don't 100% follow their reasoning, the brightest minds on these issues recommend to:
* never use volatile (for threading purposes)
* for atomic data, use Interlocked functions
(If I understand everything correctly, here is where you could use volatile, too)
* otherwise, lock
The idea is (I think) that the Interlocked Functions more directly express what you intent to do, at a finer granularity.
However, volatile should work fine as well.
PLEASE keep in mind that in all the discussion I am on thin ice hear already. There are a few things that I need to read up again. It is all to the best of my knowledge and from memory, but still could be full of errors.
|
|
|
|
|
|
I've got a main cpp file that is including a header file (MyAlgorithms.h) where I'm playing around with doing algorithms the STL way with templates and iterators.
If I put the actual code for my template algorithm in the header file everything compiles and works fine. If I define it in my header file, yet put the code in its own cpp file (MyAlgorithms.cpp) I get a compile error.
I can also put the code for the template function in the main cpp file and then it compiles/runs fine.
What gives?
I can even put the code for a non-template normal old function in the MyAlgorithms.cpp file and define in the header and it's fine.
undefined reference to `int ajo::roffeltemplate<int>(int)' CppPlayground.cpp
In main:
<br />
#include <iostream><br />
#include <string><br />
#include <vector><br />
#include <algorithm><br />
#include <br />
<br />
#include "Util.h"<br />
#include "PracticalSocket.h"<br />
#include "Protocol.h"<br />
#include "MyAlgorithms.h"<br />
<br />
...<br />
<br />
<br />
int blah = ajo::roffeltemplate(1);
MyAlgorithms.h
#ifndef MYALGORITHMS_<br />
#define MYALGORITHMS_<br />
<br />
#include <string><br />
#include <vector><br />
#include <algorithm><br />
<br />
namespace ajo<br />
{<br />
<br />
#define ROFFEL 1<br />
<br />
void printroffel();<br />
<br />
template <typename t=""><br />
T roffeltemplate(T val);<br />
<br />
template <typename iter,="" typename="" t=""><br />
T sumsquares(Iter beg, Iter end, T init);<br />
<br />
<br />
}<br />
<br />
<br />
<br />
#endif /*MYALGORITHMS_*/<br />
</typename></typename></algorithm></vector></string>
MyAlgorithms.cpp
<br />
#include "MyAlgorithms.h"<br />
<br />
#include <iostream><br />
#include <string><br />
<br />
using namespace ajo;<br />
<br />
template <typename t=""><br />
T roffeltemplate(T val)<br />
{<br />
return val;<br />
}<br />
<br />
template <typename iter,="" typename="" t=""><br />
T sumsquares(Iter beg, Iter end, T init) <br />
{<br />
T result = init;<br />
for(;beg != end; ++beg) <br />
{<br />
result += (*beg) * (*beg);<br />
}<br />
return result;<br />
}<br />
<br />
void ajo::printroffel() <br />
{<br />
printf("roffel");<br />
}<br />
<br />
<br />
</typename></typename></string></iostream>
I don't think it's a make issue, although I am experimenting with Eclipse's auto-make. I could try writing the make myself like I usually do. I can force a compiler error in the MyAlgorithms files so I know they're being compiled.
|
|
|
|
|
Great... the forum ate everything in the code with angle brackets.
Also, this is compiled in linux with gnu compiler.
|
|
|
|
|
Please reformat you post.
ArmchairAthlete wrote: Great... the forum ate everything in the code with angle brackets.
Use <pre> tags to surround code, i.e.:
<pre>
code here
</pre>
and, for template, escape the < operator ( with < ).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
ArmchairAthlete wrote: Great... the forum ate everything in the code with angle brackets.
So why not just fix your post, rather than create another one?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I want to write C program about CPU Scheduling simmulator
1. use mutilevel queue for this program
2. mix batch and interactive process
3. input process from manual keyboard write
4. Show output to dos screen
Thank you
|
|
|
|
|
whats stopping you ? you dont expect US to write it for you do you ?
There's plenty of examples here and on google that deal with such things - how about you do some research, play with some code, and come back and ask specific questions
oh, and please read the note at the top of the forum - this one :- http://www.codeproject.com/script/Forums/View.aspx?fid=1647&msg=2371639[^]
Your question also 'smells like' homework - we dont do people's homework for them - most of us got where we are by solid work and application, not by cheating, so we tend to look a bit disdainfully on this sort of thing - we will help you learn, but you have to do some research and apply yourself a bit first.
'G'
|
|
|
|
|
hi everyone...
am having a system tray icon.
if i right click the icon i have to get four option.
1.about
2.minimise
3.maximise
4.exit
upto here is over...
now the problem is if i clicked minimise that should be unvisible... like if i click maximise that should be unvisible...
can help anyone?
please tell somewhat brief... because am the beginner...
thanks in advance...
|
|
|
|
|
You can use ShowWindow with SW_HIDE and SW_SHOW
|
|
|
|
|
Hi all,
I have a template function inside a class a shown below. But while compiling I am getting an error "error C2893: Failed to specialize function template 'void __thiscall Test::someFunction(T)' With the following template arguments: 'int' ". Anybody knows whats wrong with the code?
class Test<br />
{<br />
public:<br />
template<class T> void someFunction( T obj );<br />
};<br />
<br />
template<class T> void Test::someFunction( T obj )<br />
{<br />
<br />
}<br />
<br />
int main(int argc, char* argv[])<br />
{ <br />
int n = 0;<br />
Test obj;<br />
obj.someFunction( n );
return 0;<br />
}
Also if I wrote the implementation of the template function inside the class itself, then there is no error. Like..
class Test<br />
{<br />
public:<br />
template<class T> void someFunction( T obj )
{<br />
<br />
}<br />
};
|
|
|
|
|
It should be:
template <class T>
class Test
{
void function(T);
};
Maxwell Chen
modified on Friday, December 28, 2007 4:42:31 AM
|
|
|
|
|
No no thats not possible. I only need to call the function with different types.
I think the problem is with the vc6. In vc8, it is working fine.
|
|
|
|
|
Naveen,
It's a bug of Microsoft Visual C++ (6.0) compiler. There's no workaround available.
They have corrected it in the newer versions.
Please check KB article[^]
-Sarath.
"Great hopes make everything great possible" - Benjamin Franklin
|
|
|
|
|
Oh I misunderstood your question. Sorry!
Maxwell Chen
|
|
|
|
|
Hi Naveen ,
You are right the code given by you is working on VC7 and onwards
But if you want to make it possible on VC6 then please refere the code given below and make the changes accordingly. Hope this will help you.
template<class T><br />
class Test<br />
{<br />
public:<br />
void someFunction( T obj );<br />
};<br />
<br />
template<class T> <br />
void Test<T>::someFunction( T obj )<br />
{<br />
<br />
}<br />
<br />
int main(int argc, char* argv[])<br />
{ <br />
int n = 0;<br />
Test<int> obj;<br />
obj.someFunction( n );
return 0;<br />
}
The secret of life is not enjoyment
but education through experience.
- Swami Vivekananda.
|
|
|
|
|
Hi Mahesh ,
The problem with your sugeestion is that, I cannot call the obj.someFunction() with both int and long at the same time like..
int n = 0;<br />
long l = 0;<br />
obj.someFunction( n ); <br />
obj.someFunction( l );
|
|
|
|
|
I think that Naveen wants (member) function templates of a class, not class templates .
If it is a class template, the argument type is fixed when the class object is declared. So we can not invoke member functions with different input types (something like function overloading).
Maxwell Chen
|
|
|
|
|
HI Naveen and MaxWell
I am really sorry ..It was my misunderstanding.
later I worked for wht Naveen exactly want, on VC6
But it was not working then i googled,
I found the Following link
http://forums.devx.com/archive/index.php/t-82949.html[^]
The secret of life is not enjoyment
but education through experience.
- Swami Vivekananda.
|
|
|
|
|
To tell the truth, I have been 7 years not coding template stuffs.
I just tried hard to recall everything about templates (both member function template and class template), and tried with VC++2008. It works well finally.
Maxwell Chen
|
|
|
|
|