将结构传递到函数而不实例化局部变量的效率 [英] Efficiency of passing a struct to a function without instantiating a local variable

查看:140
本文介绍了将结构传递到函数而不实例化局部变量的效率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近得知,我可以通过传递aa结构到C ++中的函数来执行以下操作:



(对于不使用更合适的名称,功能,请随时更正我的名字)

  #include< iostream> 

typedef struct mystruct {
int data1;
int data2;
} MYSTRUCT;

void myfunction(MYSTRUCT _struct){
std :: cout< _struct.data1<< _struct.data2;
}

int main(){
//这是我最近学到的
myfunction(MYSTRUCT {2,3});
return 0;
}

这让我不知道这是比实例化一个本地 MYSTRUCT
并将它的值传递给函数?或者只是临时变量被删除后,只是一个方便的方法做同样的事情?



例如添加此行 #define KBIG 10000000 ,这是:

  std :: vector< MYSTRUCT& myvector1; 
for(long long i = 0; i< KBIG; i ++){
myvector1.push_back(MYSTRUCT {1,1});
}

始终比这更快:


$ b b

  std :: vector< MYSTRUCT>我的
for(long long i = 0; i MYSTRUCT localstruct = {1,1};
myvector2.push_back(localstruct);
}



我试过测试它,但结果是相当不一致,每个12秒。有时第一个会更快,其他时候不。当然,这可能是由于测试时的所有后台进程。

解决方案

简化和编译到汇编器:

  extern void emit(int); 

typedef struct mystruct {
int data1;
int data2;
} MYSTRUCT;

__attribute __((noinline))
void myfunction(MYSTRUCT _struct){
emit(_struct.data1);
emit(_struct.data2);
}

int main(){
//这是我最近学到的
myfunction(MYSTRUCT {2,3});
return 0;
}

与-O2产生:


$ b b

  myfunction(mystruct):
pushq%rbx
movq%rdi,%rbx
call emit(int)
sarq $ 32 ,%rbx
movq%rbx,%rdi
popq%rbx
jmp emit(int)
main:
movabsq $ 12884901890,%rdi
subq $ 8 ,%rsp
call myfunction(mystruct)
xorl%eax,%eax
addq $ 8,%rsp
ret


编译器意识到整个结构适合寄存器,并通过值传递方式。



故事的道德:表达意图。让编译器担心细节。



如果你需要一份副本,你需要一份副本。结束了故事。


I recently learned that I can do the following with passing a a struct to a function in C++:

(My apologies for not using a more appropriate name for this "feature" in the title, feel free to correct me)

#include <iostream>

typedef struct mystruct{
    int data1;
    int data2;
} MYSTRUCT;

void myfunction( MYSTRUCT _struct ){
    std::cout << _struct.data1 << _struct.data2;
}

int main(){
    //This is what I recently learned
    myfunction( MYSTRUCT{2,3} );
    return 0;
}

This makes me wonder is this less costly than instantiating a local MYSTRUCT and passing it by value to the function? Or is it just a convenient way to do the same only that the temporary variable is eliminated right afterwards?

For example adding this line #define KBIG 10000000, is this:

std::vector<MYSTRUCT> myvector1;
for (long long i = 0; i < KBIG; i++) {
    myvector1.push_back(MYSTRUCT{ 1,1 });
}

Consistently faster than this:

std::vector<MYSTRUCT> myvector2;
for (long long i = 0; i < KBIG; i++) {
    MYSTRUCT localstruct = { 1,1 };
    myvector2.push_back(localstruct);
}

I tried testing it, but the results were pretty inconsistent, hovering around 9-12 seconds for each. Sometimes the first one would be faster, other times not. Of course, this could be due to all the background processes at the time I was testing.

解决方案

Simplifying slightly and compiling to assembler:

extern void emit(int);

typedef struct mystruct{
    int data1;
    int data2;
} MYSTRUCT;

__attribute__((noinline))
void myfunction( MYSTRUCT _struct ){
  emit(_struct.data1);
  emit(_struct.data2);
}

int main(){
    //This is what I recently learned
    myfunction( MYSTRUCT{2,3} );
    return 0;
}

with -O2 yields:

myfunction(mystruct):
        pushq   %rbx
        movq    %rdi, %rbx
        call    emit(int)
        sarq    $32, %rbx
        movq    %rbx, %rdi
        popq    %rbx
        jmp     emit(int)
main:
        movabsq $12884901890, %rdi
        subq    $8, %rsp
        call    myfunction(mystruct)
        xorl    %eax, %eax
        addq    $8, %rsp
        ret

What happened?

The compiler realised that the entire structure fits into a register and passed it by value that way.

moral of the story: express intent. Let the compiler worry about details.

If you need a copy, you need a copy. End of story.

这篇关于将结构传递到函数而不实例化局部变量的效率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆