大并发服务器内存转换的灵活运用,memcpy的思考

在很多的网络开发中,经常会碰到一些内存转换,如下面的场景:

#define 

PACKAGE_PARSE_ERROR -1
#define PACKAGE_PARSE_OK 0  

int parse_package( int* a, int* b, int* c, int* d, char* buf, int buf_len )
{
        if( !buf || buf_len < 16 ){
                return PACKAGE_PARSE_ERROR;
        }
        memcpy( a, buf, 4 );
        memcpy( b, buf + 4, 4 );
        memcpy( c, buf + 8, 4 );
        memcpy( d, buf + 12, 4 );  

        return PACKAGE_PARSE_OK;
}

这是网络解包的过程中的一个调用,封包的过程则是逆过程。

像这样的应用其实完 全可以用整型强制转换来代替,而且效率会至少提高一倍。

为了说明问题,我们举个简单的例 子:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>  

int main()
{
        int s;
        char buffer[4];  

        memcpy(&s, buffer, 4 );
        s = *(int*)(buffer);
        return 0;
}

第10行和第11行的效果是一样的,10行采用的是内存复制,11行采用的是强制转换,为了方 便比较,我们看一下汇编代码:

pushq   %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq    %rsp, %rbp
.cfi_def_cfa_register 6
subq    $16, %rsp
leaq    -16(%rbp), %rcx
leaq    -4(%rbp), %rax
movl    $4, %edx
movq    %rcx, %rsi
movq    %rax, %rdi
call    memcpy
leaq    -16(%rbp), %rax
movl    (%rax), %eax
movl    %eax, -4(%rbp)
movl    $0, %eax
leave

代码中可以看出,内存复制方法占用了7-12行,共6行,强制转换占用了13-15行,共3 行,指令上少了一半。

深究一下其实还不止,因为第12行其实是一个函数调用,必然会有栈的 迁移,所以强制转换的效率比内存复制起码高一倍。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索内存
, int
, include
, memcpy memmove
, memcpy
, memcpy s
, 强制
, 过程
memcpy()
mqtt高并发消息服务器、1000并发 服务器配置、服务器并发测试、高并发服务器架构、服务器并发量,以便于您获取更多的相关知识。

时间: 2025-01-03 17:19:05

大并发服务器内存转换的灵活运用,memcpy的思考的相关文章

大并发服务器必备技术:sendfile

socket发送函数. int send( SOCKET s, const char FAR *buf, int len, int flags ); 如果内容是动态生成的,一般是把传输内容直接丢给buf中用send函数传输,没有优化的空 间. 文件传输则要先把内容read到buf中,因此至少两次内核调用,如果文件很大,可能会用一 个循环调用,如: while( size == PER_SIZE ) { size = read( fd, buf, PER_SIZE ); if( size >0 )

大并发服务器必备技术:writev

前面我们说过,对于静态文件的传输,用sendfile可以减少系统调用,现在我们看看动态的数据应 该如何处理. 首先,如果数据足够小(小于1024)且只有唯一的一个buffer,我们直接用 send/write 就可以了. 通常的情况下,程序可能会在多个地方产生不同的buffer,如 nginx, 第一个phase里都可能会产生buffer,放进一个chain里, 如果对每个buffer调用一次send,系 统调用的个数将直接等于buffer的个数,对于多buffer的情况会很糟. 可能大家会想到

大并发服务器必备技术:connect 异步

前面我们谈的大多是服务端与客户端的技术,服务器开发其实有时还会涉及到跨服务器的访问,比 如腾讯的拍拍服务器需要知道登录的会员信息,就需要访问会员服务器. 跨务器访问会涉及到 很多的技术,比如访问权限控制,数据同步等,这里主要来学习一下传输层. 为了更容易理解 ,我们将访问端服务器称为客户端,被访问端服务器称为服务端. 客户端发起一个连接的过程 : socket_fd = socket( AF_INET,SOCK_STREAM,0 ); ret = connect( socket_fd, (soc

大并发服务器必备技术:http 缓存

前面所说技术订都是服务器端一个人在努力,有时候也需要客户端配合. 一个链接请求过程 大致可以分成几个阶段 如果客户端发送同样的 请求,且结果都一样,我们是不是可以缓冲一下呢?是不是可以减少几步呢? 的确可以,一般来 说以下几种方法: 1.我们先试着在服务端进行缓冲,我们试着将一个已经返回的长链接发送内 容不作释放,下次请求时直接返回刚才发送的内容,这个不适用于频繁访问,适用于一些特殊的情况, 特殊的请求. 2.对于静态的文件都有上次修改时间lastupdatetime,客户端第一次请求返回的 h

大并发服务器必备技术:tcp cork

如果把tcp当成服务端与客户端的管道,cork 就是给管道加个塞子. 为什么 要加个塞子呢 ? 先来举个例子: int times = 10; while( times--) { send( sock_fd, buf, 1, 0 ) } 这段program会发送数据10次,每次就发送1个字节,这样会不会什么问题呢? 记得 以前农忙的时候,田里的稻子收割完了,要打成稻谷,就放一个打稻机子,父亲在机子旁打稻,而我则 负责抱起稻子送给他.父亲打稻的速度很快,很小的时候我每次只抱一捆稻子,就会不停 地奔

搭建一个后台服务器:服务端(异步,大并发)

上篇的阻塞模式下服务器的并发只有几K,而真正的server 像nginx, apache, yumeiz 轻轻松松处 理几万个并发完全不在话下,因此大并发的场合下是不能用阻塞的. 1W的并发是一个分隔点,如果单进程模型下能达到 的话,说明至少在服务器这块你已经很厉害了. 服务器开发就像一门气功,能不能搞出大并发,容错性处理得怎么样,就是你有没有内功,内功有 多深. 异步模式是专门为大并发而生,linux下一般用 epoll 来管理事件,下面就开始我们的异步大并发 服务器实战吧. 跟阻塞开发一样,

高并发服务器的设计之架构与瓶颈的设计

做架构设计,难免有时候被人问及系统的瓶颈在哪,那首先来了解下什么是瓶颈? 打个形象 的比方,人的嘴巴可以吞下一整个面包,但是却咽不下去,因为食管不给力,它比较细,所以嘴巴能吞 下的食物大小要受到食管的粗细限制. 城市内部每天会产生几十万件跨城快递,可是跨城的交 通不给力,只允许走小型卡车,一卡车一次就能装几千件,一天下来也不一定能投送的完. 人 在一定时间内能咽下多少食物,货运公司在一天运送多少货物,物理上叫做吞吐量,系统整体的吞吐量 等于最小区域的吞吐量. 下面这张图能够反映: 土黄色管子的流

Memcached缓存大数据时对服务器内存、CPU的影响及其对硬件的配置需求

最近公司在进行缓存框架方面的调研,我主要对Memcached在缓存大数据量情况下对系统硬件的影响和需求做了调研,以下是一些测试数据和调研结果:  Memcached缓存不同数据量测试情况:           一.测试环境配置信息    1. 缓存服务器配置信息:一共4台 ,三台是公司服务器,一台是本机         node1: 单核 1G内存         node2: 单核 1G内存         node3: 单核 1G内存         node4: 4核  8G内存    2

高并发服务器的设计之内存池的设计

不同的业务,设计也不尽相同,但至少都一些共同的追求,比如性能. 做服务器开发很多年 了,有时候被人问到,服务器性能是什么呢?各种服务器间拼得是什么呢? 简单的回答就是QPS ,并发数,但有时候想想也许也不对. QPS与并发数是针对同样的业务而言的,业务不同,相同 的服务器能承受的压力也会不同. 性能,也许可以打个俗点的比方: 服务器就是一艘船 ,性能就是船的容量,开的速度,行得是否稳当. 该用的用,该省的省.能用内存就别用IO, CPU则能少用就少用,相同的QPS,CPU和内存用的少点的性能就要