|
Regarding the user name and the critical section I just wonder if you have thought about the possibility to inform the thread that the name has changed, instead of having the thread reading the shared resource every time it needs it? This will make the user name resource thread local and you won't need any synchronization.
Here follows some thoughts that are based upon the information you've provided.
I may have interpreted your problem wrong and they may not be applicable in your situation, but perhaps you can find something useful.
Perhaps I can interest you in another article by the same author:
Optimization: Your Worst Enemy[^].
It seems to me that you're concentrating on optimizing the details in a way that you may lose the bigger picture. It's just a feeling I get from the information you've provided and I may perfectly well be wrong, but think about it. Worrying about RAM fragmentation these days, especially when you say you "allocate data from the start, I reuse them all the time". The memory manager is really clever in that aspect.
hINTModuleState wrote:
CPlayer* getPlayerByName(CString targetName)
{
for (int i=0 --> maxPlayers)
if(playersTab[i].getName()==targetName)
return &playetrsTab[i];
return NULL;
}
does much depend, if profiled, on the time spent within the string compare operations.
Well, yes, to some extent. But you have to compare it with how long it takes to iterate through the container to find it. You also have a lot of function calls that can be avoided, if you're looking for optimization.
Suppose you have a map that maps CStrings containing user names to smart pointers to objects with data for the user. Looking up the data for the user will make use of the hash table of the map class. Have a look here[^].
What I suggest is something like this:
typedef CMySmartPointerTemplate<CMyData> DataPtr_t;
std::map<CString, DataPtr_t> NameToDataMap;
DataPtr_t spCurrentData = NameToDataMap[TheUserName];
if( spCurrentData )
{
}
else
{
} This way you don't create a CString copy on the stack as the code for the template is inline, you avoid a function call for the same reason and the lookup uses a hash table for performance, to name a few advantages.
Since the CString class has both operator<() and operator>() the std::map template hash algorithm works straight up and you don't have to provide a comparison function.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Roger, if I have to do it that way, then I will also have to find mechanism on how to hold copies of many other variable attributes for evry thread (8 threads), and how to inform the threads of their values changes.
The application is a real time chess server, (ie for blitz play) and there are much attributes and references like the CPlayer::name :players elos, games moves, players running games,challenges time property,game brodcasts participants, tournament properties etc..many many.All of them I have to ensure that concurrent access to would not cause application crash or unbearable values incorrectnesses.I am really in a big scenario.
Well indeed, I confirm this second article you supplied : optimzation can easily lead me to contradict the abstractions I've done, or I should do.
It is already that even if I choose your previous solution according to which local copies of critical data attributres are hold by the concurrent threads, then I will have to violate data visibility and it will be like synchronization a certain member x is solved elswere its class extent, such that if I encounter other synchronization issue in other contexts (I have other threads than the worker threads taht are running too) then I will have to rewrite syn mechanism.
I think I will have to content myself with CriticalSection and only hiding synchrobnization within the scope of class member functions .
No, I nolonger can endure to change the container for my data : reading this std::map again only dazzles me to using it.
I didn't know about the use of hashing inside map container.
I already using hashing client-side when you choose to play a local chess game against the computer, rather than on the server : the chess algorithms keeps track of searched positions assements numbers not by recording the whole position (what piece on evry square) along with the numbers, but rather by storing a signature of the position against the actuall assesment number..becuase the tree of chess position always contains repetitions.
Instead of the maps, maybe I think of implementing hashing, in order to make getPlayerByName very quick, but I will preserve my stack table.
Indeed I didn't know that hashing will bring significant performance here. I didn't even believe that this is a context for it : now that I see it is implemented in stadard lib ! Becuase in chess, the number of positions generated is so big (mesured in KNps : kilo Nodes per soconds) that indeed the consequence is that the time spent on the would-be compare function would be non negligeable when it is accumulated. But eventually we want access to the assesment number of the position serached becuase it is the most costly number to generate in terms of time.
Any way I have developed a sort of dhashbord, ie remote monitor for the server performances by collecting key counters and feature values and I will make sure to implement the many solutions in hand and vizualize the results.
I share with you its picture, and I am going home now becuase my head is as if split in two, one part becuase of DirectShow and the other becuase oif thread synchronisation.
http://farm4.static.flickr.com/3014/2655919984_7fa6d4ee3c.jpg?v=0[^]
Our Philosophy, Mohammed Baqir Al Sadr
|
|
|
|
|
What about Multiple-Read/Single-Write Lock ? It allows Multiple reader thread at same time, and only one writer thread at a time.
Seems its more suitable for your performance requirement, Since it won't serialize multiple reader thread. Check this article[^]
Regards,
Jijo.
_____________________________________________________
http://weseetips.com[ ^] Visual C++ tips and tricks. Updated daily.
|
|
|
|
|
if I serialize between the reader and the writer, then, using simple CriticalSection, I also serialized the many readers,so I am back to the loss of time.
Your solution seem to have solved this, but looking at the code, it really frightens : there are events and counters,etc
Is it safe to use it an apply it to the many common data I have ?
Our Philosophy, Mohammed Baqir Al Sadr
|
|
|
|
|
|
Thank you Raj !
I will have to make a simulation test in order to actually see the performance impact.
I also visited your website, it is clean and beautiful to see !
Thank you for your help and the precious links.
Our Philosophy, Mohammed Baqir Al Sadr
|
|
|
|
|
What you could do is use a simple char array with a fixed size (allow only username of a certain size, not more). Then what you could do to avoid locks is the following:
You add two flags with with the name, those flags will contain a 'version' Id. Each time the writer wants to change the name, it first increments the first flag, changes the name and finally increase the second flag.
The reader will read the first flag, read the name and read the last flag. If both flags read are the same, it means that the data is not corrupted, otherwise you have to repeat the operation until both flags are identical.
Of course, this is only valid if you have a single writer, but it avoids you to use critical sections which can degrade a bit the performances.
|
|
|
|
|
Thank you for your intervention Cedric.
Your idea seem to ensure that the reader gets a consistent value even when run at the same time as the writer, but without synchronization primitives like Critical sections, so I am tempted to becuase I want to avoid time loss by synchronisation.
.
My problem, Cedric, is that indeed I do not care about data consistency as I stated in my firt message : if the reader gets a corrupted version of the name attribute because a writer is writing on it, then it is not a big problem for me.
My problem is that the application crashes when setName and getName are run simultaneously..And I would like to get the view point of people here of the impact of using multiple Critical section for the many attribute instances and the impact of the many calls that will fall on protected sections..those imptacs on overall application performance if not on the OS and its ressources as a whole !
Examining your solution, it is even that a data corruption scenario still persists unless I do syncronisation upon access to the flags..
..
Our Philosophy, Mohammed Baqir Al Sadr
|
|
|
|
|
hINTModuleState wrote: My problem is that the application crashes when setName and getName are run simultaneously..
That's why I suggested to use a fixed size char array instead of a string. In that specific case, your program won't crash: you always read/write in the same memory area, so the only thing that could go wrong is data corruption. You have to make sure that both flags are equals before doing anything with the string that you read from the reader thread. The problem with CString objects is that you might have reallocation, so in some cases you could try to access an invalid CString object, which is causing the crash. You don't have this problem with fixed size char arrays, because you are in control of everything.
By the way, setting the new flag value is an atomic operation.
|
|
|
|
|
Ah OK, maintenant je comprend pkoi le crash avec CString. Je vais sérieusment considerer l'utilisation des tableau fixe TCHAR maintenant.
Ce que je ne comprend pas encore beaucoup c'est cette est affaire des flags..Leur implémentation les rendes atomique et synchronisé vous me dites ?
Ce n'est qu'aujourdhui que je reli une autre chose contre cela :
voila cet article qui m'a été suggéré par Roger :
http://www.flounder.com/no_synchronization.htm[^]
(rechercher la ligne avec l'occurance : a++).
Meme faire des write ou des read sur un bool c'est pas syncronisé par défaut.
OK laisson tomber le détail interne de ces op, si l'incérmentation d'un int ou la mise d'un bool à la valuer vrai est atomique ou non, et regarde mon scénario suivant se basant sur la possibilté de context switch sur les thread :
suppose k'un writer (thread A) accède à name :
iStartCount++;
puis rentre dans :
name=_T("Tunisia");
avant de faire au final :
iEndCount++;
le reader B fait un while sur le code suivant pour voir est ce que
iStartCount==iEndCount :
CString getName()
{
while(true)
{
int iStartCount_localCopy=iStartCount;
CString name_localCopy=name;
int iEndCount_localCopy=iEndCount;
if(iStartCount_localCopy==iEndCount_localCopy)
return name_localCopy;
}
}
B et A peuvent rentrer concuremment dans les deux blocs :
B prend la meme valueur iStartCount positionné par A,
ensuite A lmodifie name, et B prend la valeur corrompue en meme temps que lui,
finalement un context switch se déclenche sur B et donc A a le temps pour rendre iEndCount semblable à iStartCount, ensuite B revient fait la compariason et donc juge que sa copie n'est pas corrompue.
Déjà il y a un scénario très mauvais selon quoi la valeur de iEndCount retenue par B est > que iStartCount, et cela qd le context switch effectué sur B permet à A d'exécuter encore une autre fois le bloc sité, et dans ce cas ma boucle reste infinie.....
Bon biensur ma boucle, peut etre que j'ai maladroitement implémenté votre idée (bien ke meme is B fait une copie de iStartCount et iEndCount avant name, alors il un autre scénario bizarre ici ki peu avoir lieu..
Our Philosophy, Mohammed Baqir Al Sadr
|
|
|
|
|
(I'll switch to english if you don't mind, because it is an international website)
hINTModuleState wrote: Meme faire des write ou des read sur un bool c'est pas syncronisé par défaut.
No, when you have multiple writers you can have a problem when incrementing a variable. Incrementing a variable is done in 3 steps: fetching the value in a registry, incrementing it and putting it back in memory. If two threads try to increment the variable at the same time, you can see the issue I guess (one thread fetches the value, the other one two and then they both increment their local variable).
But, when you have only one writer, you don't have such a problem. Furthermore, as said in the article, reading or writing a 32 bit value is atomic: you fetch it in one step from the memory.
hINTModuleState wrote: B et A peuvent rentrer concuremment dans les deux blocs :
B prend la meme valueur iStartCount positionné par A,
ensuite A lmodifie name, et B prend la valeur corrompue en meme temps que lui,
finalement un context switch se déclenche sur B et donc A a le temps pour rendre iEndCount semblable à iStartCount, ensuite B revient fait la compariason et donc juge que sa copie n'est pas corrompue.
Déjà il y a un scénario très mauvais selon quoi la valeur de iEndCount retenue par B est > que iStartCount, et cela qd le context switch effectué sur B permet à A d'exécuter encore une autre fois le bloc sité, et dans ce cas ma boucle reste infinie.....
Bon biensur ma boucle, peut etre que j'ai maladroitement implémenté votre idée (bien ke meme is B fait une copie de iStartCount et iEndCount avant name, alors il un autre scénario bizarre ici ki peu avoir lieu..
Mmmh, yes it seems that I overlooked something here. I need to think a bit deeper to that.
|
|
|
|
|
hINTModuleState wrote: B et A peuvent rentrer concuremment dans les deux blocs :
B prend la meme valueur iStartCount positionné par A,
ensuite A lmodifie name, et B prend la valeur corrompue en meme temps que lui,
finalement un context switch se déclenche sur B et donc A a le temps pour rendre iEndCount semblable à iStartCount, ensuite B revient fait la compariason et donc juge que sa copie n'est pas corrompue.
Désolé pour la réponse tardive. J'ai un peu réfléchi à la question et en fait une solution c'est d'inverser l'ordre de lecture des flags: le Thread A écrit le flag 1, les données puis le flag2 et le thread B lit le flag2, les données puis le flag1. Si les deux flags sont différents, B relit l'ensemble (donc les deux flags et les données).
|
|
|
|
|
Using Win32 api.
If I double click a file icon, then the file is opened. But how can I retrieve the full path name of this file. This file could be any type such as image or sound or text. Wish someone could help me out!
|
|
|
|
|
The application that opens the file has this information.
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
ice871117 wrote: If I double click a file icon, then the file is opened. But how can I retrieve the full path name of this file.
When the Shell opens a file using the associated application, the path to the file is passed to the application as a command line parameter.
Notepad C:\somefolder\somefile.txt
led mike
|
|
|
|
|
Thanks for led mike's answer
|
|
|
|
|
How about trying the API "GetFullPathName"?
|
|
|
|
|
i have a function all it does it print a CListCtrl to a text file but it is hard to read with all the data
temp.Format("%s %10s %s\r\n", m_list.GetItemText(index, 0), "-", m_list.GetItemText(index, 2));
this works but gives a output like this
some name here - text here
longer name here - text here
even longer name here - text here
short name - text here
what i want is
some name here - text here
longer name here - text here
even longer name here - text here
short name - text here
well the "- text here" should be in a line but i cant get it right here either
can anyone help me fix it ive see how to do it somewhere but cant find it now
|
|
|
|
|
locoone wrote: well the "- text here" should be in a line but i cant get it right here either
can anyone help me fix it ive see how to do it somewhere but cant find it now
Use the <pre> tags:
some name here - text here
longer name here - text here
even longer name here - text here
short name - text here Now if you want your code to produce this, try:
temp.Format("%-28s - %s\r\n", m_list.GetItemText(index, 0), m_list.GetItemText(index, 2));
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
use
temp.Format("%-50s %10s %s\r\n", m_list.GetItemText(index, 0), "-", m_list.GetItemText(index, 2));
May be thi can help you.
-@SuDhIrKuMaR@-
|
|
|
|
|
hello
i have a problem with boost 1.35 using visul studio 8:
headers and .lib are right included in the project, no compile err indeed, but the result of the compilation is only a .obj, the is no .exe, thus when i lunch the app visual says there is no .exe due to a configuration problem.
anyone has a suggestion?
thanks much!
Andrea
|
|
|
|
|
Hi,
Goto Project Project properties.
In that dialog, goto Linker->General->Output File..
Output File is the name of the exe fie.
Just check it..
Thanks and Regards.
SANTHOSH V
|
|
|
|
|
hello
i checked it but it was ok: $(OutDir)\$(ProjectName).exe
i also renamed in: main.exe
sorry but it doesn't solve the problem...
the message that appears says to check the manifest file, but nothing useful i see.
anyone has some idea?
thanks
Andrea
|
|
|
|
|
Hi All,
I tried searching for the appropriate forum for posting queries about Windows kernel and drivers and conclude that this one is the most appropriate.
In case this forum is not the best place, please suggest a suitable forum.
Thanks,
Numero Uno.
|
|
|
|
|
In case of programming questions, this would be the right place. If you have general questions related to drivers, go to the hardware/device driver forum.
Thanks Roger for pointing out.
Many are stubborn in pursuit of the path they have chosen, few in pursuit of the goal - Friedrich Nietzsche
.·´¯`·->Rajesh<-·´¯`·.
[Microsoft MVP - Visual C++]
modified on Tuesday, August 19, 2008 9:28 AM
|
|
|
|
|