Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Pull request for c# driver - reduce locking patch

Received: by 10.66.90.102 with SMTP id bv6mr1803557pab.34.1344873498430;
        Mon, 13 Aug 2012 08:58:18 -0700 (PDT)
X-BeenThere: mongodb-csharp@googlegroups.com
Received: by 10.68.116.38 with SMTP id jt6ls3442365pbb.8.gmail; Mon, 13 Aug
 2012 08:58:18 -0700 (PDT)
Received: by 10.68.233.226 with SMTP id tz2mr1877263pbc.13.1344873498048;
        Mon, 13 Aug 2012 08:58:18 -0700 (PDT)
Date: Mon, 13 Aug 2012 08:58:17 -0700 (PDT)
From: mongotime <hmekhs...@gmail.com>
To: mongodb-csharp@googlegroups.com
Message-Id: <f5c34215-9e96-4798-8977-7d40f09868af@googlegroups.com>
In-Reply-To: <8e3b5823-84af-411f-ae8b-094f23a66bdb@googlegroups.com>
References: <f6386c95-4047-498d-aa91-aa64a6619435@googlegroups.com>
 <80C4AA13-1701-4389-8369-FC208B713556@gmail.com>
 <d2131901-8015-48dd-a020-d1b6dde0dec7@googlegroups.com>
 <25190a34-94ab-47b8-b917-c52a4d58cd8a@googlegroups.com>
 <8e3b5823-84af-411f-ae8b-094f23a66bdb@googlegroups.com>
Subject: Re: [mongodb-csharp] Pull request for c# driver - reduce locking
 patch
MIME-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_530_25209741.1344873497612"

------=_Part_530_25209741.1344873497612
Content-Type: multipart/alternative; 
	boundary="----=_Part_531_8305633.1344873497612"

------=_Part_531_8305633.1344873497612
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit

Since we are on the subject on optimizations, I had done some hotspot 
analysis of driver back in 1.3 and had found that the next best thing to 
optimize was the use of HashTables instead of Dictionary + Lock in certain 
places. Created a 50% boost in some theoretical cpu-bound tests. See below 
if interested:

https://groups.google.com/d/msg/mongodb-csharp/Ff81lTXg-gU/axixImQGlWMJ





On Friday, August 10, 2012 6:24:27 PM UTC-7, craiggwilson wrote:
>
> It's not the Creating of the servers that has the stale __cache read 
> problem, it's the reading elsewhere in the code.  Regardless, I'd like to 
> renew my question of how often are you calling this method?  Since this 
> class is safe to throw into your IoC container (or whatever you are doing), 
> then why are you calling this method so often?  (There may be a valid 
> reason, I'd just like to hear it :).
>
>
>
> On Friday, August 10, 2012 6:17:55 PM UTC-5, nuk nuk wrote:
>>
>> A Thread.MemoryBarrier() might do the trick on the first cacheRef = 
>> __cache;
>>
>> The issue is that every reader imposes a yield. Under mine and most users 
>> scenarios, the __cache will be rarely written to, yet a lock is imposed on 
>> every reader.
>>
>> Regarding volatile - we may still be OK. Under current code, the thread 
>> must yield because lock() {} is called. Under the proposed code, a yield is 
>> not mandated when the current cache has the item.
>>
>>
>> Assuming non-volatile __cache declaration, there are 2 dry-cache outcomes:
>> 1 - that the __cache does not have the url
>> 2 - that the "real" __cache (new one) has it, but the reader sees the old 
>> __cache (dry)
>> In either event, the lock(){} then steps in, and imposes the isolation 
>> and full sync with main memory. the __cach is then re-gotten , but never 
>> modified. It is copied over and then the main __cache reference is 
>> atomically swapped.
>> The assignment of the __cache object is always done with an effectively 
>> read-only value. __cache is not modified because the reference to it is 
>> grabbed once. If while a thread is reading __cache another is in the lock, 
>> the __cache may be swapped mid code, but cacheRef variable has a point in 
>> time reference to __cache. If cache is then modified by another thread, the 
>> reader still has the old one, and at most would be compelled to call for a 
>> lock and try creating a new MongoUrl() but that would not happen due to the 
>> second check.
>>   
>>
>> On Friday, August 10, 2012 4:10:07 AM UTC-7, craiggwilson wrote:
>>>
>>> We are constrained to .NET 3.5 at the moment, so we cannot use the 
>>> concurrent collections from .NET 4.0.
>>>
>>> NukNuk, that is the proper procedure.  We simply missed it.  My 
>>> apologies.  Regarding your pull request, are you creating so many 
>>> MongoServer's that this is important.  It adds a bit of complexity that 
>>> seems unnecessary to me.  In addition, this only satisfies conditions a 
>>> strong memory models.  To account for a weak memory model (like Itanium 
>>> processors), you'll need to add volatile to the __cache member or create a 
>>> memory barrier before reading it.
>>>
>>> On Friday, August 10, 2012 5:16:07 AM UTC-5, Daniel Harman wrote:
>>>>
>>>> No skin in this game, but wouldn't concurrent dictionary be more 
>>>> appropriate, or is the driver held back to support those on .net 1.0? ;) 
>>>>
>>>> Sent from my iPad 
>>>>
>>>> On 10 Aug 2012, at 01:12, nuk nuk <shlu...@gmail.com> wrote: 
>>>>
>>>> > Hi, 
>>>> > 
>>>> > I submitted a pull request a while back - never got any action or 
>>>> traction. https://github.com/mongodb/mongo-csharp-driver/pull/118 
>>>> > Is there some other procedure to submit patches? Do i need to contact 
>>>> someone directly? 
>>>> > 
>>>> > 
>>>> > Thanks! 
>>>>
>>>
------=_Part_531_8305633.1344873497612
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Since we are on the subject on optimizations, I had done some hotspot analy=
sis of driver back in 1.3 and had found that the next best thing to optimiz=
e was the use of HashTables instead of Dictionary + Lock in certain places.=
 Created a 50% boost in some&nbsp;theoretical&nbsp;cpu-bound tests. See bel=
ow if interested:<div><br></div><div>https://groups.google.com/d/msg/mongod=
b-csharp/Ff81lTXg-gU/axixImQGlWMJ</div><div><br></div><div><br><div><br></d=
iv><div><br><br>On Friday, August 10, 2012 6:24:27 PM UTC-7, craiggwilson w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">It's not the Creating of =
the servers that has the stale __cache read problem, it's the reading elsew=
here in the code. &nbsp;Regardless, I'd like to renew my question of how of=
ten are you calling this method? &nbsp;Since this class is safe to throw in=
to your IoC container (or whatever you are doing), then why are you calling=
 this method so often? &nbsp;(There may be a valid reason, I'd just like to=
 hear it :).<div><br></div><div><br><br>On Friday, August 10, 2012 6:17:55 =
PM UTC-5, nuk nuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0=
;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">A Thread.Me=
moryBarrier() might do the trick on the first cacheRef =3D __cache;<br><br>=
The issue is that every reader imposes a yield. Under mine and most=20
users scenarios, the __cache will be rarely written to, yet a lock is=20
imposed on every reader.<br>
<br>Regarding volatile - we may still be OK. Under current code, the thread=
 must yield because lock() {} is called. Under the proposed code, a yield i=
s not mandated when the current cache has the item.<br><br><br>Assuming non=
-volatile __cache declaration, there are 2 dry-cache outcomes:<br>1 - that =
the __cache does not have the url<br>2 - that the "real" __cache (new one) =
has it, but the reader sees the old __cache (dry)<br>In either event, the l=
ock(){} then steps in, and imposes the isolation and full sync with main me=
mory. the __cach is then re-gotten , but never modified. It is copied over =
and then the main __cache reference is atomically swapped.<br>The assignmen=
t of the __cache object is always done with an effectively read-only value.=
 __cache is not modified because the reference to it is grabbed once. If wh=
ile a thread is reading __cache another is in the lock, the __cache may be =
swapped mid code, but cacheRef variable has a point in time reference to __=
cache. If cache is then modified by another thread, the reader still has th=
e old one, and at most would be compelled to call for a lock and try creati=
ng a new MongoUrl() but that would not happen due to the second check.<br>&=
nbsp; <br><br>On Friday, August 10, 2012 4:10:07 AM UTC-7, craiggwilson wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex">We are constrained to .NET 3.5 a=
t the moment, so we cannot use the concurrent collections from .NET 4.0.<di=
v><br></div><div>NukNuk, that is the proper procedure. &nbsp;We simply miss=
ed it. &nbsp;My apologies. &nbsp;Regarding your pull request, are you creat=
ing so many MongoServer's that this is important. &nbsp;It adds a bit of co=
mplexity that seems unnecessary to me. &nbsp;In addition, this only satisfi=
es conditions a strong memory models. &nbsp;To account for a weak memory mo=
del (like Itanium processors), you'll need to add volatile to the __cache m=
ember or create a memory barrier before reading it.</div><div><br>On Friday=
, August 10, 2012 5:16:07 AM UTC-5, Daniel Harman wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">No skin in this game, but wouldn't concurrent dictio=
nary be more appropriate, or is the driver held back to support those on .n=
et 1.0? ;)
<br>
<br>Sent from my iPad
<br>
<br>On 10 Aug 2012, at 01:12, nuk nuk &lt;<a>shlu...@gmail.com</a>&gt; wrot=
e:
<br>
<br>&gt; Hi,
<br>&gt;=20
<br>&gt; I submitted a pull request a while back - never got any action or =
traction. <a href=3D"https://github.com/mongodb/mongo-csharp-driver/pull/11=
8" target=3D"_blank">https://github.com/mongodb/<wbr>mongo-csharp-driver/pu=
ll/118</a>=20
<br>&gt; Is there some other procedure to submit patches? Do i need to cont=
act someone directly?
<br>&gt;=20
<br>&gt;=20
<br>&gt; Thanks!
<br></blockquote></div></blockquote></blockquote></div></blockquote></div><=
/div>
------=_Part_531_8305633.1344873497612--

------=_Part_530_25209741.1344873497612--