简体   繁体   English

有效地通过值传递多大的结构?

[英]How large structs can be passed by value efficiently?

The rule of thumb is that it is okay to pass small structs by value and larger ones should be done pointers. 经验法则是按值传递小结构是可以的,而较大的结构应该是指针。

My question is where exactly is this cutoff point? 我的问题是这个截止点究竟在哪里? How large can the structures be before you are better off passing them by pointer. 在你最好通过指针传递结构之前,结构有多大。

I know this will vary between platforms, but I assume some rough estimates could be given. 我知道这会因平台而异,但我假设可以给出一些粗略的估计。 A year or two ago I tried to figure out this on the PPC architecture and found to my surprise that one could pass quite a lot of data efficiently by value. 一两年前,我试图在PPC架构上弄清楚这一点,并且令我惊讶的是,人们可以通过价值有效地传递大量数据。 Think 10 double values or so was just fine due to the large number of registers in PPC. 由于PPC中存在大量寄存器,因此认为10个左右的值很合适。 By pointer actually involved more copying in and out of memory. 指针实际上涉及更多的内存复制和内存复制。

However I now I am on intel and I expect things could be different. 但是我现在我在英特尔,我希望事情可能会有所不同。 Since the CPU don't have that many registers traditionally, but perhaps that is different on 64bit or floating point registers? 由于CPU传统上没有那么多寄存器,但在64位或浮点寄存器上可能有所不同?

Okay, so I tried to follow advice and profile my code with using pointers and value. 好的,所以我尝试遵循建议并使用指针和值来描述我的代码。 I also looked at the assembly code. 我还看了汇编代码。 It seems that the performance characteristics on x86 are quite different from PPC. 似乎x86上的性能特征与PPC完全不同。 On PPC the binary interface to C specified that arguments would be put into registers (there were so many to chose from), however it seems that even on 64bit x86 requires arguments to be put on the stack. 在PPC上,C的二进制接口指定参数将被放入寄存器(有很多可供选择),但似乎即使在64位x86上也需要将参数放在堆栈上。

So that explains why on x86 passing by pointer always seems to be faster. 这就解释了为什么在x86上通过指针总是看起来更快。 However I noticed the compiler is very eager to inline. 但是我注意到编译器非常渴望内联。 So it didn't matter in which way I did it. 所以我做到了这一点无关紧要。 So I guess the conclusion is to use whatever passing which is convenient to you. 所以我猜结论是使用任何方便你的传球。

I think that favors pass by value, because working on copies of values is somewhat safer. 我认为有利于价值传递,因为处理价值副本更安全一些。 My test case was a struct consisting of 4 doubles (so I guess that makes it 32 bytes on most platforms). 我的测试用例是一个由4个双精度组成的结构(所以我想这在大多数平台上都是32字节)。

If you search the web you'll find some guidelines about byte size for passing by reference and value. 如果您在网上搜索,您会找到一些关于字节大小的指南,以便通过引用和值传递。 I would trust pretty much none of it. 我几乎都不相信它。 The only way to know that a particular struct is a problem is to 知道特定结构是一个问题的唯一方法是

Profile It 简介它

This is the only way to know 100% that there is a problem. 这是100%知道存在问题的唯一方法。

Before the naysayers jump in. Yeah there are some obvious cases out there. 在反对者进入之前。是的,那里有一些明显的案例。 I would not for instance ever pass a struct by value if it had say 100 members. 例如,如果说有100个成员,我就不会按值传递结构。 But that wouldn't be for performance issues, it would be more for stack space problems. 但这不是针对性能问题,而是针对堆栈空间问题。

In C++ there's the rule to pass everything not on the following list as const reference because the performanceis essentially never worse. 在C ++中,规则是将不在以下列表中的所有内容作为const引用传递,因为性能基本上不会更糟。 The list of exceptions is: 例外列表是:

  • elementary types ( int etc.), 基本类型( int等),
  • pointers, 指针,
  • empty types (tag types), 空类型(标签类型),
  • function-like types (functors), and 类似函数的类型(仿函数),和
  • iterators. 迭代器。

I'm not sure if this can be applied directly to C (apart from the obvious types that C doesn't have) but maybe a similar guideline applies. 我不确定这是否可以直接应用于C(除了C没有的明显类型),但也许适用类似的指南。

Some compilers may make the optimal size determination for you. 有些编译器可能会为您确定最佳尺寸。 If I remember correctly, the TI28xx compiler automatically converts pass by value to pass by reference if the structure is above a certain size. 如果我没记错的话,如果结构超过一定的大小,TI28xx编译器会自动将pass by值转换为按引用传递。

Don't neglect the part that alignment plays in your testing. 不要忽视对齐在测试中扮演的角色。 If you're passing floats or doubles around and your structures aren't aligned on appropriate boundaries, the processor may wind up fetching part of your value, shifting it, then ORing the rest in before storing it. 如果您正在传递浮动或双重并且您的结构未在适当的边界上对齐,则处理器可能会取出您的部分值,移动它,然后在存储它之前对其余部分进行OR运算。 I think most modern compilers will DTRT (by aligning the struct when it's declared), but if you're optimizing for space then this will likely be an issue. 我认为大多数现代编译器都是DTRT(通过在声明时对齐结构),但如果你正在优化空间,那么这可能是一个问题。

Hmmm, now that I think about it, take this with a grain of salt, as I haven't done any low-level coding on the x86 arch since the Pentium Pro... 嗯,现在我考虑一下,考虑到这一点,因为我没有在x86拱门上做任何低级编码,因为奔腾Pro ...

Usually primitive types I pass by value, everything else by reference. 通常原始类型我通过值传递,其他所有通过引用传递。 That's my rule of the thumb. 这是我的拇指规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM