digitalmars.D.learn - Overhead of synchronized class used in unshared situation
- breezes (3/3) Nov 27 2011 I have several cumtermized data structures which will be used both in sh...
- Jonathan M Davis (7/14) Nov 27 2011 If your class is synchronized, then you get the overhead. If you really ...
- breezes (7/7) Nov 27 2011 Thanks. It seems that I have to write two classes, one synchronized and ...
- Jonathan M Davis (28/38) Nov 27 2011 Neither is exactly good, but casting away shared would probably be bette...
- Timon Gehr (5/12) Nov 28 2011 The first one.
I have several cumtermized data structures which will be used both in shared and unshared situations. Because un-synchronized classes can not be used in shared situation, I think i have to define these classes as synchronized classes, because otherwise i will have to write the same class twice. However, if those classes are used in unshared situations, such as local variable or unshared global variable, does the overhead of synchronized still remain? I'm writing database in which performance is critical.
Nov 27 2011
On Sunday, November 27, 2011 13:53:49 breezes wrote:I have several cumtermized data structures which will be used both in shared and unshared situations. Because un-synchronized classes can not be used in shared situation, I think i have to define these classes as synchronized classes, because otherwise i will have to write the same class twice. However, if those classes are used in unshared situations, such as local variable or unshared global variable, does the overhead of synchronized still remain? I'm writing database in which performance is critical.If your class is synchronized, then you get the overhead. If you really want to use a class both in a situation which is shared and one which is not and only synchronize the shared case, then you need two separate classes. An alternative would be to use a wrapper class which is synchronized and use the wrapper when you care about synchronization and not use it otherwise. - Jonathan M Davis
Nov 27 2011
Thanks. It seems that I have to write two classes, one synchronized and one is not. Of course the synchronized one should be the wrapper. However, all members of a synchronized class are also shared. So I can not use the un-synchronized class in the synchronized wrapper class directly. I found two ways to overcome this problem: 1. Cast away shared whenever using the wrapped un-synchronized object. 2. Define the wrapped un-synchronized object as __gshared. Which way if more preferred?
Nov 27 2011
On Monday, November 28, 2011 06:37:39 breezes wrote:Thanks. It seems that I have to write two classes, one synchronized and one is not. Of course the synchronized one should be the wrapper. However, all members of a synchronized class are also shared. So I can not use the un-synchronized class in the synchronized wrapper class directly. I found two ways to overcome this problem: 1. Cast away shared whenever using the wrapped un-synchronized object. 2. Define the wrapped un-synchronized object as __gshared. Which way if more preferred?Neither is exactly good, but casting away shared would probably be better - just be aware that in doing so you are then losing any guarantees that shared gives you with regards to threads. _You_ must guarantee that a shared object which has been cast to non-shared isn't actually shared between threads, since as soon as you cast away shared, the compiler is free to assume that the object is thread-local. __gshared basically makes something act like it would in C or C++, so the compiler really doesn't give any guarantees with regards to it, and it should generally only be used when interacting with C or C++ code. As I understand it, however, you _should_ be able to have object as a member variable in a synchronized class and still be able to use it without it being shared. The problem is IIRC that you have to mark an functions on it that you intend to be able to use when it's shared as shared and will probably have to duplicate those functions. So, you could essentially end up duplicating the entire class anyway (though mixin templates and string mixins would make it easy enough to avoid actually having to duplicate the code as far as what you maintain goes). A _class_ isn't shared or not. It's an instantiated object which is shared or not, and shared objects can only call shared functions. So, that may be part of what's throwing you off. But as I said, the situation does risk more code duplication than would be desirable (or force you to use mixins of some variety to avoid such duplication). If you're running into major problems with shared, I'd advise bringing it up in the main D newsgroup. There have been a variety of discussions about it lately - including some possible adjustments to how it works - since a number of people have been running into issues when trying to use it on anything other than a fairly small scale. - Jonathan M Davis
Nov 27 2011
On 11/28/2011 07:37 AM, breezes wrote:Thanks. It seems that I have to write two classes, one synchronized and one is not. Of course the synchronized one should be the wrapper. However, all members of a synchronized class are also shared. So I can not use the un-synchronized class in the synchronized wrapper class directly. I found two ways to overcome this problem: 1. Cast away shared whenever using the wrapped un-synchronized object. 2. Define the wrapped un-synchronized object as __gshared. Which way if more preferred?The first one. You manually ensure, by locking, that the object is actually unshared during that particular time frame and that there are memory fences. Casting away shared makes that information available to the compiler.
Nov 28 2011