Jump to content

Recommended Posts

Posted

Can anyone please tell what a DVR [ Data value reference ] is ? I want to know at what situation it will be used and what are the advantages we get by using DVR. I am really confused in this topic . If someone has any code in which they have worked with DVRs. kindly share it to me.

 

Thank you.

Posted (edited)

I don't have good examples to share, but here are a few helpful links for you:

Quote

A Data Value Reference (DVR) is shared memory location where the location to the data is passed on the wire as a reference rather than passing the data. It keeps memory copies from being created by using In Place Element Structures to read and write to the data. DVRs are automatically locked from other writers while a process is writing to it and has the option for multiple parallel reads. 

-- https://labviewwiki.org/wiki/Data_Communication#Data_Value_Reference_.28DVR.29

NI has an article dedicated to DVRs, which also explains the fundamental idea: http://www.ni.com/product-documentation/9386/en/

Here is a short video that explains how to use a DVR and some of the pitfalls: https://www.youtube.com/watch?v=VIWzjnkqz1Q

Of course, you'll find lots of topics related to DVRs on this forum.

Edited by LogMAN
  • Like 1
  • 5 years later...
Posted
On 9/27/2019 at 8:13 AM, Ram Prakash said:

Can anyone please tell what a DVR [ Data value reference ] is ? I want to know at what situation it will be used and what are the advantages we get by using DVR. I am really confused in this topic . If someone has any code in which they have worked with DVRs. kindly share it to me.

 

Thank you.

Discussion forums like LAVA and ni.com are challenged these days by LLMs that can answer in a well structured manner very quickly and handle follow-up questions on the spot.

Forums have their stenghts, but when it comes to basic questions that LLMs can find a lot about, spread across multiple forums, the LLMs win. It is a bit of a catch 22 though, as the LLMs need the forums alive to stay up to date 😮 
 

------------------------------
Here is Grok answering you question of what a DVR is:

  • DVRs as References: In LabVIEW, DVRs (Data Value References) are a mechanism to access data by reference rather than by value. This means that instead of creating copies of the data (as is typical in LabVIEW's dataflow paradigm), a DVR provides a pointer-like reference to a single memory location where the data resides. This avoids unnecessary data duplication, which can be critical for large datasets or performance-sensitive applications.
     
  • Avoiding Copies: By using DVRs, you can manipulate the same data in memory without creating copies, which is especially useful for large arrays, clusters, or other complex data structures. This reduces memory usage and improves performance.
     
  • Parallel Operations and Race Conditions: When multiple parallel operations (e.g., parallel loops or VIs) access the same DVR, there is a potential for race conditions if the access is not properly synchronized. LabVIEW provides the In-Place Element Structure to safely access and modify DVR data. This structure ensures that only one operation can read or write to the DVR at a time, preventing race conditions. Without this, simultaneous read/write operations could lead to unpredictable results or data corruption.
Key Points to Add:
  • Thread Safety: DVRs are not inherently thread-safe. You must use the In-Place Element Structure (or other synchronization mechanisms like semaphores) to avoid race conditions when multiple parallel tasks access the same DVR.
  • Use Cases: DVRs are commonly used in scenarios where you need to share data between parallel loops, modules, or processes without copying, such as in real-time systems or when managing shared resources.
  • Limitations: DVRs are only valid within the application instance where they are created, and the data they reference is freed when the reference is deleted or the application stops.

---------------------


Before DVRs we typically had to resort to cloning of functional globals (VIs), but DVRs make this a little more dynamic and slick. You can have a single malleable VI operate on multiple types of DVRs too e.g.,  that opens up a lot of nice reuse. If you have an object that requires multiple circular buffers e.g. you can include circular buffer objects in the private data of that object, with the circular buffer objects containing a DVR to an array acting as that buffer...

--------------------

Here is ChatGPT comparing functional globals with DVRs:

Functional Globals (FGs) and Data Value References (DVRs) are both techniques used in programming (particularly in LabVIEW) to manage shared data, but they offer different approaches and have different strengths and weaknesses. FGs encapsulate data within a VI that provides access methods, while DVRs provide a reference to a shared memory location. 
 
Functional Globals (FGs): 
 
  • Encapsulation:
    FGs encapsulate data within a VI, often a subVI, that acts as an interface for accessing and modifying the data. This encapsulation can help prevent unintended modifications and promote better code organization.
  • Control over Access:
    The FG's VI provides explicit methods (e.g., "Get" and "Set" operations) for interacting with the data, allowing for controlled access and potential validation or error handling.
  • Potential for Race Conditions:
    While FGs can help avoid some race conditions associated with traditional global variables, they can still be susceptible if not implemented carefully, particularly if the access methods themselves are not synchronized.
  • Performance:
    FGs can introduce some overhead due to the VI calls, but this can be mitigated by using techniques like inlining and careful design.
  • Example:
    An FG could be used to manage a configuration setting, with a "Get Configuration" and "Set Configuration" VI providing access to the settings. 
     
Data Value References (DVRs):
 
  • Shared Memory Reference:
    DVRs are references to a memory location, allowing multiple VIs to access and modify the same data. This is a more direct way of sharing data than FGs.
  • Flexibility:
    DVRs can be used with various data types, including complex data structures, and can be passed as parameters to subVIs.
  • Potential for Race Conditions:
    DVRs, like traditional globals, can be prone to race conditions if not handled carefully. Proper synchronization mechanisms (e.g., queues, semaphores, or action engines) are often needed to prevent data corruption.
  • Performance:
    DVRs can be very efficient, especially when used with optimized data access patterns.
  • Example:
    A DVR could be used to share a large array between different parts of an application, with one VI writing to the array and another reading from it. 
     
Key Differences and Considerations:
 
  • Control vs. Flexibility:
    FGs offer more control over data access through their defined interface, while DVRs offer more flexibility in terms of the data types and structures that can be shared.
  • Race Condition Mitigation:
    While both can be susceptible, FGs can be designed with built-in synchronization mechanisms (like action engines), while DVRs require explicit synchronization mechanisms to prevent race conditions.
  • Performance Trade-offs:
    DVRs can offer better performance in many cases, especially when dealing with large data sets, but this can be offset by the complexity of managing synchronization.
  • Code Readability and Maintainability:
    FGs can make code more readable and maintainable by encapsulating data access logic, but poorly designed FGs can also lead to confusion. 
     
In summary:
 
  • Use Functional Globals when:
    You need controlled access to data, want to encapsulate data management logic, or need to ensure some level of synchronization.
  • Use Data Value References when:
    You need to share data efficiently between multiple parts of your application, need flexibility in the data types you are sharing, or when performance is critical and synchronization can be handled externally. 
     
It's worth noting that in many cases, a combination of both techniques might be used to leverage the strengths of each approach. For example, a DVR might be used to share data, while a functional global (or an action engine) is used to manage access to that data in a controlled and synchronized manner. 
Posted (edited)
2 hours ago, Mads said:

Discussion forums like LAVA and ni.com are challenged these days by LLMs that can answer in a well structured manner very quickly and handle follow-up questions on the spot.

I've just spent an hour arguing with an LLM (Deepcoder). :D TL;DR A.I. is useless at programming.

I had a bug. I'd spent about an hour trying to figure it out and not succeeding but it shouldn't be that hard-I'm just missing something obvious. So. Ideal scenario for a clever AI to show dominance and help out a poor old flesh-bag programmer, right? Just point out the mistake or mistakes and laugh at my stupidity like a real coder.

The bug was that the address from recvfrom would be 0.0.0.0 instead of 127.0.0.1.  The problem was either bind wasn't binding to a specific address (which it was supposed to) or the address translation was not working quite right. I gave it 3 functions where I thought the bug was and explained that IPv6 seemed to be reporting correctly but IPv4 was in error:

  1. one function (Listen) had the bind function
  2. one function had IPv6 and IPv4 address translation from a SOCKADDR_STORAGE structure to strings and
  3. the other function was the read function with the recvfrom.

This is an abbreviation of the conversion: 

- Round one.

The following code has a bug that returns 0.0.0.0 as the IPv4 address from "recvfrom" when it should be returning "127.0.0.1". Find the reason that the code is returning 0.0.0.0 instead of 127.0.0.1 and rewrite the code to fix the issue.

It told me how to bind to a specific address and how to use the recvfrom function. It then basically wrote the example on the MS page for recvfrom but within the Listen function.

- Round 2.

I'm not using the "sockaddr_in" structures; I'm using SOCKADDR_STORAGE structures. Please modify your example to use SOCKADDR_STORAGE structures.

It apologised made an excuse about misunderstanding and then proceeded to create an example, still using sockaddr_in structures, but this time hardcoding "127.0.0.1" in the bind address.

- Round 3.

No, no, no. It needs to support user entered IPv6 and IPv4 but there is a bug with the IPv4 address. It also needs to use SOCKADDR_STORAGE as in the code I supplied to you. Reevaluate the code and write a version of the code that fixes the bug.

It apologised, said that it understands why it got it wrong, and then proceeded to create an example, still using sockaddr_in structures, but now hardcoding "::1" in the bind address. :frusty:

-Round 4.

Look. It needs to support both IPv6 and IPv4 and that's the reason I'm using SOCKADDR_STORAGE. If you don't have enough information then ask for clarification but you have the code that the bug is in so find the damned bug FFS!

Another apology, said it can understand my frustration and then proceeded to spit out the example from MS again.

This went on for an hour. No code I could actually use in my functions, never pointed out the bug in my code and the prompts just got longer and longer as I tried to head-off it's stupidity.

This was one of the functions.

int Addr2Address(SOCKADDR_STORAGE addr, PCHAR Address, int *Port, int *IPvType) {
    int err = 0;
    *IPvType = 0;
    switch (addr.ss_family) {
        case AF_INET6: {
                if (Address == NULL) {return 46;}
                *IPvType = 2;
                char strAddress[46];
                inet_ntop(addr.ss_family, (void*)&((sockaddr_in6 *)&addr)->sin6_addr, Address, sizeof(strAddress));
                break;
            }
        case AF_INET: {
                if (Address == NULL) {return 16;}
                *IPvType = 1;
                char strAddress[16];
                inet_ntop(addr.ss_family, (void*)&((sockaddr_in6 *)&addr)->sin6_addr, Address, sizeof(strAddress));
                break;
            }
        default: {err = WSAEPROTONOSUPPORT; break;}
    }
    *Port = ntohs(((sockaddr_in6 *)&addr)->sin6_port);
    return err;
}

The bug is in the AF_INET case.

inet_ntop(addr.ss_family, (void*)&((sockaddr_in6 *)&addr)->sin6_addr, Address, sizeof(strAddress));

It should not be an IPv6 address conversion, it should be an IPv4 conversion. That code results in a null for the address to inetop which is converted to 0.0.0.0.

I found it after a good nights sleep and a fresh start.

Edited by ShaunR

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.