Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(net/ghttp): Using assembly instead of reflection to call routing on the AMD64 platform #3682

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

wln32
Copy link
Member

@wln32 wln32 commented Jul 13, 2024

在amd64平台用汇编代替反射调用路由

@gqcn
Copy link
Member

gqcn commented Jul 17, 2024

@wln32 这块代码有点hack了,能描述一下这里使用unsafe包以及汇编的必要性吗?值得一提的是,unsafe包我之前在框架中有使用过,主要是string[]byte的转换,在某些场景下会引起一些意想不到的错误,直接进程崩溃,后面全部删除了unsafe的使用。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@wln32 This code is a bit of a hack. Can you describe the necessity of using the unsafe package and assembly here? It is worth mentioning that I have used the unsafe package in the framework before, mainly for the conversion of string to []byte. In some scenarios, it will cause some unexpected errors and directly cause the process to crash. The use of unsafe will be deleted later.

@wln32
Copy link
Member Author

wln32 commented Jul 17, 2024

@wln32 这块代码有点hack了,能描述一下这里使用unsafe包以及汇编的必要性吗?值得一提的是,unsafe包我之前在框架中有使用过,主要是string[]byte的转换,在某些场景下会引起一些意想不到的错误,直接进程崩溃,后面全部删除了unsafe的使用。

@gqcn 其实string[]byte的转换在其他库里面也很常见,你说的意想不到的错误,可能是修改了原字符串导致的,gostring是只读的,使用unsafe转换为[]byte后,不能修改其中的内容,否则会panic

关于这里使用unsafe以及汇编,算是我的一个验证吧,刚开始的时候我就一直在想能不能直接使用如下的方法签名来统一调用,以此消除反射的开销。
函数签名:func(ctx context.Context, req unsafe.Pointer)(res unsafe.Pointer,err error)
我尝试了一下直接使用反射来获取每个方法的空接口,然后断言,发现不行,直到前段时间,我看了下汇编,觉得汇编应该可以实现我之前的想法,试了下 发现可以,原理其实差不多算是方法转发吧,转发参数以及接受返回值,目前来看,这个汇编写的应该没毛病,可以不用合并这个

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@wln32 This code is a bit of a hack. Can you describe the necessity of using the unsafe package and assembly here? It is worth mentioning that I have used the unsafe package in the framework before, mainly for the conversion of string to []byte. In some scenarios, it will cause some unexpected errors and directly cause the process to crash. The use of unsafe will be deleted later.

@gqcn In fact, the conversion of string to []byte is also very common in other libraries. The unexpected error you mentioned may be caused by modifying the original string. string of go is read-only Yes, after using unsafe to convert it to []byte, the contents cannot be modified, otherwise it will panic.

Regarding the use of unsafe and assembly here, it is my verification. At the beginning, I have been wondering whether I can directly use the following method signature to call uniformly, so as to eliminate the overhead of reflection.
Function signature: func(ctx context.Context, req unsafe.Pointer)(res unsafe.Pointer,err error)
I tried using reflection directly to get the empty interface of each method, and then asserted that it didn't work. Until some time ago, I looked at the assembly and felt that the assembly should be able to realize my previous idea. After trying it, I found that it can. The principle is actually It's almost like method forwarding, forwarding parameters and accepting return values. At present, there should be no problem with writing this assembly, so you don't need to merge it.

@wln32
Copy link
Member Author

wln32 commented Jul 17, 2024

@wln32 这块代码有点hack了,能描述一下这里使用unsafe包以及汇编的必要性吗?值得一提的是,unsafe包我之前在框架中有使用过,主要是string[]byte的转换,在某些场景下会引起一些意想不到的错误,直接进程崩溃,后面全部删除了unsafe的使用。

@gqcn 其实string[]byte的转换在其他库里面也很常见,你说的意想不到的错误,可能是修改了原字符串导致的,gostring是只读的,使用unsafe转换为[]byte后,不能修改其中的内容,否则会panic

关于这里使用unsafe以及汇编,算是我的一个验证吧,刚开始的时候我就一直在想能不能直接使用如下的方法签名来统一调用,以此消除反射的开销。 函数签名:func(ctx context.Context, req unsafe.Pointer)(res unsafe.Pointer,err error) 我尝试了一下直接使用反射来获取每个方法的空接口,然后断言,发现不行,直到前段时间,我看了下汇编,觉得汇编应该可以实现我之前的想法,试了下 发现可以,原理其实差不多算是方法转发吧,转发参数以及接受返回值,目前来看,这个汇编写的应该没毛病,性能跟调用普通方法差了只有四五倍,可以不用合并这个pr

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@wln32 This code is a bit of a hack. Can you describe the necessity of using the unsafe package and assembly here? It is worth mentioning that I have used the unsafe package in the framework before, mainly for the conversion of string to []byte. In some scenarios, it will cause some unexpected errors and directly cause the process to crash. The use of unsafe will be deleted later.

@gqcn In fact, the conversion of string to []byte is also very common in other libraries. The unexpected error you mentioned may be caused by modifying the original string. string of go is only For reading, after using unsafe to convert it to []byte, the content cannot be modified, otherwise it will panic.

Regarding the use of unsafe and assembly here, it is my verification. At the beginning, I have been wondering whether I can directly use the following method signature to call uniformly, so as to eliminate the overhead of reflection. Function signature: func(ctx context.Context, req unsafe.Pointer)(res unsafe.Pointer,err error) I tried to directly use reflection to obtain the empty interface of each method, and then asserted that it did not work until the previous paragraph. Time, I looked at the assembly and felt that the assembly should be able to realize my previous idea. I tried it and found that it was possible. The principle is actually method forwarding, forwarding parameters and accepting return values. At present, there should be nothing wrong with this assembly. , the performance is only four or five times worse than calling ordinary methods, so there is no need to merge this pr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants