Professional OPC
Development Tools

logos

Browsing The Address Space Quickly

More
09 Oct 2014 18:29 - 09 Oct 2014 18:32 #2416 by support
I have made a measurement of node browsing speed. I wrote a simple program that goes through the whole address space, dumps the nodes, counts the branches and leaves, and measures the time needed. Here is a relevant part of it:
 
// This example shows how to recursively browse the nodes in the OPC address space.
using System;
using System.Diagnostics;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
 
namespace DocExamples
{
    namespace _EasyDAClient
    {
        partial class BrowseNodes
        {
            public static void Recursive()
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
 
                var easyDAClient = new EasyDAClient();
                _branchCount = 0;
                _leafCount = 0;
                BrowseFromNode(easyDAClient, "OPCLabs.KitServer.2", "");
 
                stopwatch.Stop();
                Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds);
                Console.WriteLine("Branch count: {0}", _branchCount);
                Console.WriteLine("Leaf count: {0}", _leafCount);
            }
 
            private static void BrowseFromNode(
                EasyDAClient client,
                ServerDescriptor serverDescriptor,
                DANodeDescriptor parentNodeDescriptor)
            {
                Debug.Assert(client != null);
                Debug.Assert(serverDescriptor != null);
                Debug.Assert(parentNodeDescriptor != null);
 
                // Obtain all node elements under parentNodeDescriptor
                var nodeFilter = new DANodeFilter();    // no filtering whatsoever
                DANodeElementCollection nodeElementCollection = 
                    client.BrowseNodes(serverDescriptor, parentNodeDescriptor, nodeFilter);
                // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
                // it, here omitted for brevity.
 
                foreach (DANodeElement nodeElement in nodeElementCollection)
                {
                    Debug.Assert(nodeElement != null);
 
                    Console.WriteLine(nodeElement);
 
                    // If the node is a branch, browse recursively into it.
                    if (nodeElement.IsBranch)
                    {
                        _branchCount++;
                        BrowseFromNode(client, serverDescriptor, nodeElement);
                    }
                    else
                    {
                        _leafCount++;
                    }
                }
            }
 
            private static int _branchCount;
            private static int _leafCount;
        }
    }
}
 

It takes it approx. 800 milliseconds to browse the whole address space of our simulation server, which (in my test) consists of 236 branches and 1619 leaves (giving approx. 7 leaves per branch on average, which I think may also resemble a real server).

This gives means approx. 0.5 millisecond per leaf (with more leaves per branch, which is also common, results would be better, because fewer calls would be needed).
First time it takes a bit longer, but that's because of the time needed to connect.
Also, it is possible that a significant proportion of the time is actually taken by the console output itself - I have not tried to remove it, because the speed is sufficient already for me to make the point.

For larger address space (which I can also create if needed, but haven't done that yet), this should scale linearly. So, for example, 50000 leaves would take just 25 seconds.

Obviously, this is just a local scenario (both OPC client and server are on the same machine), and a fast server, but nothing extraordinary. In a remote scenario, or with a slower server, times will be longer, but all OPC clients will be affected in the same way.

In my perception, the results here are not just satisfactory - they are VERY fast, in fact. If you are seeing something else, I suggest that you start by trying my example first, with our simulation server, and verify the speed. Then, start modifying the code towards your needs, and observe at which point the speed gets worse.

Best regards
Last edit: 09 Oct 2014 18:32 by support.

Please Log in or Create an account to join the conversation.

More
07 Oct 2014 13:32 #2400 by support
Thank you for the detailed description of your needs.

Without using a spec like OPC A&E, or modifying the server so that the required operation is done in a much simpler way (using a single tag for example), I believe that with OPC DA, you have to go through the full browse, at some point.

So the question remains only how effectively it can be done. If any other OPC client can do it significantly faster than QuickOPC, we are strongly interested in matching its speed. I just need to determine whether that's the case. As I wrote, I will make the speed tests in the lab.

Please Log in or Create an account to join the conversation.

More
07 Oct 2014 12:33 #2397 by OndrejBlazek
I will try to get some statistics (number of tags, branches, etc) back to you but it might be easier to just cut to the chase...

We are writing a module that needs to take a wild card pattern, a desired value, and set the Enabled property of all OPC tags (in the Address Space) to the desired value.

The purpose of this module is to allow SCADA operators to suspend signals (alarms) for a specific device, or group of devices, or devices at a location. Typically one would use this module when a controlled shutdown is being executed in order to avoid tripping numerous alarms. For example, when a train is being shutdown, all signals for that train would first be inhibited (using this module) to avoid numerous communication lost signals and other train related signals from tripping as the train shuts down. The module also provides an option for automatically re-enabling the signals after a time period (to ensure that the operator does not forget to re-enable the train alarms for future).

Since we want to keep the module generic (i.e. not specific to a specific address space) we need some way to identify all OPC tags that match the provided tag pattern. Since OPC DA does not support wild card subscriptions, I figured that reading the address space (storing it) and then performing patten matches on the results would allow me to determine all OPC tags that match the pattern. However, if the initial read of the Address Space will take hours then this is not a viable solution.

Do you have any suggestions on how this can be implemented using your OPC Easy DA Client?

Please Log in or Create an account to join the conversation.

More
07 Oct 2014 06:55 #2392 by support
My understanding is that you actually do not have a comparable test, i.e. an OPC client that would truly give you the whole address space. Correct?

Nevertheless, when I come back to the office, probably towards end of this week, I will make an evaluation of QuickOPC browse speed, and compare it to others.

But I think you are not putting things right. From what you described, there is no reason to think that ICONICS Sample Client does the whole browse upfront, and quickly. The fact that expanding an individual branch appears "quick" does not imply that doing the same for e.g. 5000 branches will be "quick" as well, because for multiplying by 5000 , you really need to know what the first multiplier is. Half a second would look quick to the user, but 5000 times will yield three quarters of an hour. 100 milliseconds would look about as quick, but will yield approx. 8 minutes total.

What is the number of branches, and the number of tags, in your OPC Server?

For my testing, please share with me the QuickOPC version and build number you are using.

Please Log in or Create an account to join the conversation.

More
06 Oct 2014 19:42 #2389 by OndrejBlazek
The ICONICS Sample OPC Client is not built from a toolkit. It is a very simple OPC DA Client for reading OPC DA values for troubleshooting purposes when configuring ICONICS screens using the ICONICS Genesis 64 product suite.

The point I was trying to make it that when we use the client, it seems to perform a complete Address Space browse because it provides the Address Space as a Tree Node which you can navigate with no delays after the initial Address Space read. This leads me to believe that the entire Address Space was read initially and then just visualized as a Tree Node.

When using these type of third party clients, the Address Space seems to be browsed in a matter of a couple minutes (at most) as opposed to the much longer time it would take with the Easy DA Client.

Please Log in or Create an account to join the conversation.

More
06 Oct 2014 13:43 #2387 by support
How can you tell the ICONICS sample client to browse the whole address space?

Please Log in or Create an account to join the conversation.

More
06 Oct 2014 12:48 #2382 by OndrejBlazek
The solution provided, in other threads, for browsing the entire address space (when needed) is to use recursive Browse calls and store the information until the entire address space is mapped.

I have use the provided sample code, streamlined it (removing the reading of data item values) to make it run as fast as possible.

Testing it on our server still resulted in a execution time well past many minutes (I am guessing hours).

What this tells me is that the OPC Labs Browse code is either very inefficient or the OPC DA 1.0/2.0 specifications provide an alternate method of obtaining the address space (which OPC Labs may not have implemented). The reason for this is that other, third party applications, are able to read the entire address space of our server is much less time. For example, the Sample OPC Client that comes with ICONICS, is able to read the entire address space in less than 2 minutes compared to the hours result that I would get with OPC Labs.

Any comment?

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.186 seconds

      

 Recommend this on Google