整个数组可以驻留在某些CPU寄存器中吗?
由于我对 cpu 寄存器不太熟悉,一般来说,在任何体系结构中,特别是 x86 中,如果使用 VC++ 与编译器相关,我很好奇数组的所有元素是否都可以像数组一样具有少量元素1 字节字符和 4 个元素驻留在某个 cpu 寄存器中,因为我知道这对于双精度、整数等单个基元可能是正确的?
当我们有一个像下面这样的参数时:
void someFunc(char charArray[4]){
//whatever
}
这个参数传递是否肯定是通过将指针传递给函数来完成的,或者该数组将驻留在某个CPU寄存器中,从而无需将指针传递给主内存?
As I'm not too much familiar with cpu registers, in general and in any architecture specially x86 and if compiler-relevant using VC++ I'm curious that is it possible for all elements of an array with a tiny number of elements like an array of 1-byte characters with 4 elements to reside in some cpu register as I know this could be true for single primitives like double, integer, etc ?
when we have a parameter like below:
void someFunc(char charArray[4]){
//whatever
}
Will this parameter passing be definitely done through passing a pointer to the function or that array would be residing in some cpu register eliminating the need to pass a pointer to main memory?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这不依赖于编译器,也不可能。数组不能像其他类型一样按值传递,即它们在传递到函数时不能被复制。 C++ 标准很明确,在处理声明中的函数签名时,以下是完全等价的:
兼容的编译器会将函数签名中的数组转换为指针。现在,在调用处,会发生类似的操作:如果参数是数组,编译器必须将其分解为指向第一个元素的指针。同样,数组的大小在衰减中丢失。
特定的寄存器可用于保存多个值并对它们执行操作(谷歌搜索向量化操作、MME 和变体)。但是,虽然这意味着编译器实际上可以将小数组的内容插入到单个寄存器中,但这不能用于更改您引用的函数调用。
This is not compiler dependent, nor is it possible. Arrays cannot be passed by value in the same way as other types, i.e. they cannot be copied when passed into a function. The C++ standard is clear in that when processing a function signature in a declaration the following are exact equivalencies:
A compliant compiler will convert the array in the function signature into a pointer. Now, at the place of call, a similar operation takes place: if the argument is an array, the compiler has to decay it into a pointer to the first element. Again, the size of the array is lost in the decay.
Specific registers can be used to hold more than one value and perform operations on them (google for vectorized operations, MME and variants). But while that means that the compiler can actually insert the contents of a small array into a single register, that cannot be used to change the function call that you refer to.
在单个函数中,只要编译器能够生成 CPU 指令来按照代码的指示操作数组,数组就可以保存在一个或多个寄存器中。该标准并没有真正定义寄存器中“存在”的含义。这是编译器和调试器之间的私人事务,并且寄存器中的某些内容与完全“优化掉”之间可能存在细微的界限。
在您的示例中,参数是一个指针,而不是一个数组(请参阅 dribeas 的答案)。因此,它指向的数组可能保存在寄存器中是不寻常的。您可能处理的“主”体系结构不允许指向寄存器的指针,因此即使数组保存在调用代码中的寄存器中,也必须将其写入内存才能获取指向寄存器的指针它,传递给被调用者。
如果函数调用是内联的,那么可能会有更好的优化,就像根本没有调用一样。
如果将数组包装在结构体中,则可以将其转换为可以按值传递的内容:
现在,该函数将实际的数组数据作为其参数,因此将其保存在寄存器中的障碍减少了。不过,实现的调用约定是否确实在寄存器中传递小结构是另一个问题。我不知道什么调用约定可以做到这一点(如果有的话)。
Within a single function, an array could be held in one or more registers, just so long as the compiler is able to produce CPU instructions to manipulate it as the code dictates. The standard doesn't really define what it means for something to "be" in a register. It's a private matter between the compiler and the debugger, and there may be a fine line between something being in a register, and being "optimized away" entirely.
In your example, the parameter is a pointer, not an array (see dribeas' answer). So it would be unusual that the array it points to could possibly be held a register. The "main" architectures that you probably deal with don't allow a pointer to a register, so even if the array was held in a register in the calling code, it would have to be written into memory in order to take a pointer to it, to pass to the callee.
If the function call was inlined, then better optimizations might be possible, just as if there were no call at all.
If you wrap your array in a struct, then you turn it into something that can be passed by value:
Now, the function is taking the actual array data as its parameter, so there's one less barrier to holding it in a register. Whether the implementation's calling convention actually does pass small structs in registers is another question, though. I don't know what calling conventions do this, if any.
在我相当熟悉的 5 个左右编译器中,(Borland/Turbo C/C++ 从 1.0 开始,Watcom C/C++ 从 v8.0 开始,MSC 从 5.0 开始,IBM Visual Age C/C++,DOS 上各种版本的 gcc 、Linux 和 Windows)我还没有看到这种优化自然发生。
有一个字符串库,我不记得它的名字了,它在 x86 ASM 中做了类似的优化。它可能是“自发组装”库的一部分,但不能保证。
Out of the 5 or so compilers I'm fairly familiar with, (Borland/Turbo C/C++ from 1.0, Watcom C/C++ from v8.0, MSC from 5.0, IBM Visual Age C/C++, gcc of various versions on DOS, Linux and Windows) I've not seen this optimization happen naturally.
There was a string library, whose name I cannot remember, that did optimizations similar to this in x86 ASM. It may have been part of the "Spontaneous Assembly" library, but no guarantees.
接受数组的函数可能会索引到该数组。据我所知,没有任何体系结构支持对寄存器进行有效索引,因此在寄存器中传递数组可能毫无意义。
(在 x86 架构上,您可以通过访问
al
和ah
来访问a[0]
和a[1]
> eax 寄存器,但这是一种特殊情况,仅当索引在编译时已知时才有效。)A function that accepts an array is probably going to index into that array. I know of no architecture that supports efficient indexing into a register, so it's probably pointless to pass arrays in registers.
(On an x86 architecture, you could access
a[0]
anda[1]
by accessingal
andah
of theeax
register, but that is a special case that only works if the indexes are known at compile time.)您询问在 x86 上使用 VC++ 是否可行。
我怀疑这种配置是否可行。确实,您可以生成将数组保存在寄存器中的汇编程序代码,但由于数组的性质,它绝不是编译器的自然优化,因此我怀疑他们是否将其放入其中。
您可以尝试一下并生成一些代码,编译器有“激励”将其放入寄存器中,但它看起来很奇怪,就像
使用优化和 /FA 开关编译它并查看生成的汇编代码(然后告诉我们结果:-))
如果您以更“自然”的方式使用它,例如访问单个字符或使用字符串初始化它,则编译器根本没有理由将该数组放入寄存器中。
即使将其传递给函数 - 编译器也可能会将数组的地址放入寄存器中,而不是数组本身
You asked if its possible with VC++ on an x86.
I doubt it's possible in that configuration. True, you could produce assembler code where that array is kept in a register, but due to the nature of arrays it would be by no means a natural optimization for a compiler, so I doubt they put it in.
You can try it out though and produce some code where the compiler would have an "incentive" to put it in a register, but it would look pretty weird like
Compile that with optimizations and the /FA switch and look at the assembler code produced (and then tell us the results :-))
If you use it in a more "natural" way, like accessing single characters or initializing it with a string there is no reason at all for the compiler to put that array into a register.
Even when passing it to a function - the compiler might put the address of the array into the register, but not the array itself
只有变量可以存储在寄存器中。您可以尝试使用
register
关键字强制寄存器存储:register int i;
数组默认是指针。
您可以像这样获取位于 4 位置的值(使用指针语法):
Only variables can be stored in a register. You can try to force register storage by using the
register
keyword:register int i;
Arrays are by default pointers.
You can get the value located at the 4 position like this (using pointer syntax):