- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
传值和传引用
在现在常用的文本编程语言(C++, Java, C#)中,调用子函数时的传参方式主要是传引用方式,就是说,告诉被调用的函数的是参数所在的位置,而不是参数的数据。C++ 为了保持和 C 语言的兼容,一般的简单数据还是使用值传递,但对于大块的数据,比如数组,字符串,结构,类等等,也基本上都是引用形式传递的。
值传递的方式的缺点是显而易见的:每次调用子函数的时候,需要把数据拷贝一份,耗费大量的内存。传引用的方式,不需要每次都拷贝数据,节省了内存空间,和复制数据的时间。但是传引用的安全性不如直接传值,因为传引用的时候,数据所在的内存也可以被其它函数访问,这在单线程下,问题不大。但是多线程下,就不能保证数据的安全了。
理论上,一个数据流驱动的编程语言,可以只采用值传递。数据在每一个联线分叉的地方,都做一个拷贝。这样任何一个节点所处理的数据都是它专用的,不需要担心线程之间会相互影响。在设计 LabVIEW 程序时,可以假设 LabVIEW 就是这样子工作的。但是 LabVIEW 的实际工作情况比这要复杂些,它在不违背数据流原则的前提下,做了一些优化以避免过多的复制数据。
在某些时候,一个节点得到了输入数据,LabVIEW 如果能够确认这个输入数据的内存肯定不会被其他部分的程序代码使用到,并且恰好节点的一个输出需要一块内存,LabVIEW 就不在为输出数据令开辟一块内存了,而是使用那个输入数据所在的内存。这叫做缓存重用。
这种行为实质上和传引用是一样的,告诉函数一个数据的地址,然后函数直接在这个地址上处理数据。LabVIEW 程序员是不能够直接设置某个参数是传值还是传引用的。到底采用那种传递方式,是由 LabVIEW 来决定的。LabVIEW 决定采用哪种参数传递方式的原则是:首先保证数据的安全,其次才估计效率。LabVIEW 并不能总是准确的判断出某段代码采用传引用的方式是否安全。LabVIEW 本着宁枉勿纵的原则,对凡是拿不准的地方一律不优化,全部采用传值的方式,多拷贝一份数据。
虽然不能够直接设置某个参数是传值还是传引用的,但追求效率的的程序员,可以通过改变程序风格,来帮助 LabVIEW 准确判断出那些代码可以优化,无需拷贝数据,从而让自己编写出来的 LabVIEW 代码效率最高。比如,使用移位寄存器和缓存重用结构告诉 LabVIEW 在某个地方使用传引用的方式。
LabVIEW 中有些节点的输入输出数据类型完全不一样,比如数组索引节点,输入是一个数组和索引,输出是一个数组的元素。输入和输出的数据类型一般情况下完全不同,所以必须未输出数据新开辟一块内存,根本不可能做到缓存重用。有些节点,总是有相同类型的输入输出,比如加法节点,输出值的数据类型总是和其中一个输入同类型(fixed-point 数据类型是个例外)。LabVIEW 要考虑尽量在这些节点使用缓存重用。
如果输入值是数组数据,它通过分叉的连线被同时输入到一个数组索引节点和一个加法节点。假设其它数据都已就绪,LabVIEW 作为数据流驱动的程序,理论上应该同时运行着两个节点。但实际上,为了内存优化,在类似的情况下,LabVIEW 总是运行不可能做缓存重用的节点(比如这里是数组索引节点),然后再运行可以做缓存重用的节点(加法节点)。
原因是这样的:如果先运行加法节点或者同时运行两个节点,因为加法节点的输入数据所在的内存还要被数组索引节点读取,因而加法节点是不能够改变这块内存中的数据的,那么加法节点只好再为输入数据开辟一块新内存;相反,如果先运行完数组索引节点,在运行加法节点的时候,加法节点输入数据所在的内存就不会再被别的节点使用了,这是加法节点就可以放心的把输入数据放到这块内存里,做到缓存重用。
LabVIEW 虽然不能设置数据传递给一个节点时,使用值传递还是引用传递,但是 LabVIEW 中有一类专门的“引用型控件”,用来保证大块的数据不被频繁复制,或者在不同的线程内对同一内存做数据操作。一般叫做 xxx refnum 的控件都属于之一类,他们所代表的数据(也可用于表示某个设备)是不随着数据线流动的。程序上的连线出现分叉,虽然 refnum 这个值本身可能会被复制,但它所指向的数据是不会被拷贝的。
另外,如果一定要在 LabVIEW 代码中实现传引用,可以通过以下的方法:做一个全局数组变量,把数据存在数组里。VI 间传递的信息是数据在数组中的索引,一个表示序号整数值,就相当于是这块数据的引用。这样,所有对块数据的操作都是在同一内存中的,并且不同线程可以同时对这块内存做修改。
文档评论(0)