[jboss-jira] [JBoss JIRA] (DROOLS-529) Thread contention during NodeSegment momory initialisation and creating child segments in org.drools.core.phreak.SegmentUtilities#createSegmentMemory and org.drools.core.phreak.SegmentUtilities#createChildSegments
Ravi Sanwal (JIRA)
issues at jboss.org
Tue Jun 17 19:49:24 EDT 2014
Ravi Sanwal created DROOLS-529:
----------------------------------
Summary: Thread contention during NodeSegment momory initialisation and creating child segments in org.drools.core.phreak.SegmentUtilities#createSegmentMemory and org.drools.core.phreak.SegmentUtilities#createChildSegments
Key: DROOLS-529
URL: https://issues.jboss.org/browse/DROOLS-529
Project: Drools
Issue Type: Enhancement
Security Level: Public (Everyone can see)
Affects Versions: 6.0.1.Final
Reporter: Ravi Sanwal
Assignee: Mark Proctor
Priority: Critical
In our perf test we noticed a lot of monitor wait time around these synchronized methods. This is creating thread contention eventually causing throughput loss.
In our general uses, we have around 3k rules, we create knowledge base with these 3k rules. Multiple threads evaluate rules from this knowledge base, every thread creates a new stateless session.
During evaluation we noticed this contention. Because these methods are globally synchronized the performance (and concurrency is poor).
We did some comparison between PHREAK and RETEOO and found that RETEOO was 10x faster. I can provide some sample rules to assert this behavior, if needed.
I don't have much idea about segment memory etc. but I think, looking at the codebase, that the synchronization can be narrowed down to specific working memory instances (for specific session).
I modified the synchronization on these methods a bit as below and it did increase the performance, not sure if this is actually the correct way. This however is still slower that RETEOO. This time the performance was CPU bound and in comparision to RETEOO, RETEOO was 4x faster.
Here is what I changed
{code}
public static void createChildSegments(final InternalWorkingMemory wm, final SegmentMemory smem, final LeftTupleSinkPropagator sinkProp) {
synchronized (smem) {
if (!smem.isEmpty()) {
return; // this can happen when multiple threads are trying to initialize the segment
}
synchronized (wm) {
for (LeftTupleSinkNode sink = sinkProp.getFirstLeftTupleSink(); sink != null; sink = sink.getNextLeftTupleSinkNode()) {
final Memory memory = wm.getNodeMemory((MemoryFactory) sink);
final SegmentMemory childSmem = createChildSegment(wm, sink, memory);
smem.add(childSmem);
}
} //end wm synchronization
} //end smem synchronization
}
{code}
and
{code}
public static SegmentMemory createSegmentMemory(LeftTupleSource tupleSource, final InternalWorkingMemory wm) {
synchronized (wm) {
SegmentMemory smem = wm.getNodeMemory((MemoryFactory) tupleSource).getSegmentMemory();
if (smem != null) {
return smem; // this can happen when multiple threads are trying to initialize the segment
}
.....
{code}
--
This message was sent by Atlassian JIRA
(v6.2.6#6264)
More information about the jboss-jira
mailing list