1,摘要:测试send和sendmsg的性能,影响这两个函数性能主要有发送的字节大小,增加循环次数,从100到10000000(千万)
2,基本信息
cat /proc/cpuinfo查看CPU信息,如下:

  Intel(R) Xeon(R) CPU E5-2698 v3 @ 2.30GHz

cat /proc/version 查看操作系统内核版本,如下:

  Linux version 3.10.0-327.el7.x86_64

cat /proc/meminfo查看内存信息,如下:

  MemTotal: 131748016 kB
  MemFree: 42526620 kB
  MemAvailable: 60623924 kB

3,send性能测试

服务器端 : nc -lu 8888

客服端:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include<time.h>
#include <sys/times.h>
#include <unistd.h>
//#define BUFSIZ 1024
#define recycle 1000000
static inline uint64_t rte_rdtsc(void)
{
union {
uint64_t tsc_64;
struct {
uint32_t lo_32;
uint32_t hi_32;
};
}tsc;
asm volatile("rdtsc":
"=a" (tsc.lo_32),
"=d" (tsc.hi_32)); return tsc.tsc_64;
}
int recycleSet[]={,,,,,,,,,,};
int bufsizeSet[]={,,,,,,}; int main(int argc,char *argv[])
{
/*if(argc<3)
{
printf("paramaters error! ./socet_sendmsg 1000 1024");
return -1;
}
int recycle_times=atoi(argv[1]);
int buf_len=atoi(argv[2]);
*/
int sockfd,numbytes;
//char buf[BUFSIZ]; int sc_clk_tck;
sc_clk_tck = sysconf(_SC_CLK_TCK);
sc_clk_tck = sysconf(_SC_CLK_TCK);
struct sockaddr_in their_addr;
//printf("break! sc_clk_tck=%d\n",sc_clk_tck);
while((sockfd = socket(AF_INET,SOCK_DGRAM,)) == -);
//printf("We get the sockfd~\n");
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons();
their_addr.sin_addr.s_addr=inet_addr("192.168.10.8");
bzero(&(their_addr.sin_zero), ); while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -);
// printf("Get the Server~Cheers!\n"); 濉濞绔俊姣
// numbytes = recv(sockfd, buf, BUFSIZ,0);//妤娑?
// buf[numbytes]='\0';
// printf("%s",buf); //clock_t start_time,end_time;
// start_time=clock();
int buf_i=;
for(buf_i=;buf_i<;buf_i++){
int buf_len=bufsizeSet[buf_i];
char *buf=(char *)calloc(buf_len,sizeof(char));
int i=;
for(i=;i<buf_len;i++)
{
buf[i]='a' + rand()%;
}
buf[buf_len]='\0';
int recycle_i=;
for(recycle_i=;recycle_i<;recycle_i++){
int recycle_times=recycleSet[recycle_i];
struct timeval start_time,end_time;
gettimeofday(&start_time,NULL);
uint64_t start=rte_rdtsc();
for(i=;i<recycle_times;i++)
{ numbytes = send(sockfd, buf, strlen(buf), );
//numbytes=recv(sockfd,buf,BUFSIZ,0);
//buf[numbytes]='\0';
//printf("send:%d\n",numbytes);
}
uint64_t end=rte_rdtsc();
//end_time=clock();
gettimeofday(&end_time,NULL);
uint64_t duration=end-start;
double duration_time=*(end_time.tv_sec-start_time.tv_sec)+(end_time.tv_usec-start_time.tv_usec);
//printf("recycle_times=%d duration=%f numbytes=%d duration_rte=%f\n",recycle_times,duration_time,numbytes,duration/2.2);
printf("%d,%d,%d, %f ,%f,%f\n",recycle_times,numbytes,buf_len,duration_time,duration/2.2,duration_time*1.0/recycle_times);
}
}
close(sockfd);
return ;
}

4,sendmsg性能测试(iovlen=1)

服务器端:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
/************************************************************************************************************************ *************************************************************************************************************************/
int main(int argc, char *argv[])
{
int fd, new_fd, struct_len, numbytes,i;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buff[BUFSIZ];
//struct msghdr msg;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = INADDR_ANY;
// bzero(&(server_addr.sin_zero), 8);
struct_len = sizeof(struct sockaddr_in);
while((fd = socket(AF_INET,SOCK_DGRAM,0)) == -1);
if (bind(fd, (struct sockaddr*)(&server_addr), struct_len) < 0)
{
fprintf(stderr, "bind fail\n");
exit(EXIT_FAILURE);
}
printf("Bind Success!\n");
// fd = socket(AF_INET, SOCK_DGRAM, 0);
/*while(bind(fd, (struct sockaddr *)&server_addr, struct_len) == -1);
printf("Bind Success!\n");
while(listen(fd, 100) == -1);
printf("Listening....\n");
printf("Ready for Accept,Waitting...\n");
new_fd = accept(fd, (struct sockaddr *)&client_addr, &struct_len);
*/
//printf("Get the Client.\n");
// numbytes = send(new_fd,"Welcome to my server\n",21,0);
while(1)
{
printf("recemsg\n");
struct msghdr msg;
bzero(&msg,sizeof(struct msghdr));
msg.msg_name =&client_addr;
msg.msg_namelen =sizeof(struct sockaddr_in);
struct iovec io;
io.iov_base =buff;
io.iov_len =BUFSIZ;
msg.msg_iov = &io;
msg.msg_iovlen = 1;
numbytes = recvmsg(fd,&msg,0);
char * temp = msg.msg_iov[0].iov_base;//获取得到的数据
temp[numbytes] = '\0';//为数据末尾添加结束符
// printf("get %d message:%s", numbytes,temp);
printf("get %d \n", numbytes);
}
// close(new_fd);
close(fd);
return 0;
}

  客服端:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include<time.h>
#include <sys/times.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
//#define BUFSIZ 1024
#define recycle 1000000
static inline uint64_t rte_rdtsc(void)
{
union {
uint64_t tsc_64;
struct {
uint32_t lo_32;
uint32_t hi_32;
};
}tsc;
asm volatile("rdtsc":
"=a" (tsc.lo_32),
"=d" (tsc.hi_32)); return tsc.tsc_64;
}
int recycleSet[]={100,500,1000,5000,10000,50000,100000,500000,1000000,5000000,10000000};
int bufsizeSet[]={128,256,512,1024,2048,3072,4096}; int main(int argc,char *argv[])
{
/*if(argc<3)
{
printf("paramaters error! ./socet_sendmsg 1000 1024");
return -1;
}
int recycle_times=atoi(argv[1]);
int buf_len=atoi(argv[2]);
*/
int sockfd,numbytes;
//char buf[BUFSIZ]; int sc_clk_tck;
sc_clk_tck = sysconf(_SC_CLK_TCK);
struct sockaddr_in their_addr;
//printf("break! sc_clk_tck=%d\n",sc_clk_tck);
while((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1);
//printf("We get the sockfd~\n");
bzero(&their_addr, sizeof(their_addr));
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(8888);
their_addr.sin_addr.s_addr=inet_addr("192.168.10.8");
//their_addr.sin_addr.s_addr=htonl(INADDR_ANY);
//bzero(&(their_addr.sin_zero), 8); // while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1);
// printf("Get the Server~Cheers!\n");
// numbytes = recv(sockfd, buf, BUFSIZ,0);//接收服务器端信息
// buf[numbytes]='\0';
// printf("%s",buf); //clock_t start_time,end_time;
// start_time=clock();
int buf_i=0;
for(buf_i=0;buf_i<7;buf_i++){
int buf_len=bufsizeSet[buf_i];
char *buf=(char *)calloc(buf_len,sizeof(char));
int i=0;
for(i=0;i<buf_len;i++)
{
buf[i]='a' + rand()%26;
}
buf[buf_len]='\0';
struct msghdr msg;
bzero(&msg,sizeof(struct msghdr));
//msg.msg_name = NULL;
msg.msg_name = &their_addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
struct iovec io;
io.iov_base = buf;
io.iov_len = buf_len;
msg.msg_iov = &io;
msg.msg_iovlen = 1;
int recycle_i=0;
for(recycle_i=0;recycle_i<11;recycle_i++){
int recycle_times=recycleSet[recycle_i];
struct timeval start_time,end_time;
gettimeofday(&start_time,NULL);
uint64_t start=rte_rdtsc();
for(i=0;i<recycle_times;i++)
{ //numbytes = send(sockfd, buf, strlen(buf), 0);
numbytes = sendmsg(sockfd, &msg, 0);
//numbytes=recv(sockfd,buf,BUFSIZ,0);
//buf[numbytes]='\0';
//printf("send:%d\n",numbytes);
}
uint64_t end=rte_rdtsc();
//end_time=clock();
gettimeofday(&end_time,NULL);
uint64_t duration=end-start;
double duration_time=1000000*(end_time.tv_sec-start_time.tv_sec)+(end_time.tv_usec-start_time.tv_usec);
//printf("recycle_times=%d duration=%f numbytes=%d duration_rte=%f\n",recycle_times,duration_time,numbytes,duration/2.2);
printf("%d,%d,%d, %f ,%f,%f\n",recycle_times,numbytes,buf_len,duration_time,duration/2.2,duration_time*1.0/recycle_times);
}
}
close(sockfd);
return 0;
}

4,sendmsg性能测试(iovlen=4)

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include<time.h>
#include <sys/times.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
//#define BUFSIZ 1024
#define recycle 1000000
static inline uint64_t rte_rdtsc(void)
{
union {
uint64_t tsc_64;
struct {
uint32_t lo_32;
uint32_t hi_32;
};
}tsc;
asm volatile("rdtsc":
"=a" (tsc.lo_32),
"=d" (tsc.hi_32)); return tsc.tsc_64;
}
int recycleSet[]={100,500,1000,5000,10000,50000,100000,500000,1000000,5000000,10000000};
int bufsizeSet[]={128,256,512,1024,2048,3072,4096,5120,6144,7168,8192,9216,15000,150000};
#define BUF_CNT 14
int main(int argc,char *argv[])
{
/*if(argc<3)
{
printf("paramaters error! ./socet_sendmsg 1000 1024");
return -1;
}
int recycle_times=atoi(argv[1]);
int buf_len=atoi(argv[2]);
*/
int sockfd,numbytes;
//char buf[BUFSIZ]; int sc_clk_tck;
sc_clk_tck = sysconf(_SC_CLK_TCK);
struct sockaddr_in their_addr;
//printf("break! sc_clk_tck=%d\n",sc_clk_tck);
while((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1);
//printf("We get the sockfd~\n");
bzero(&their_addr, sizeof(their_addr));
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(9999);
their_addr.sin_addr.s_addr=inet_addr("192.168.10.8");
//their_addr.sin_addr.s_addr=htonl(INADDR_ANY);
//bzero(&(their_addr.sin_zero), 8); // while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1);
// printf("Get the Server~Cheers!\n");
// numbytes = recv(sockfd, buf, BUFSIZ,0);//接收服务器端信息
// buf[numbytes]='\0';
// printf("%s",buf); //clock_t start_time,end_time;
// start_time=clock();
int buf_i=0;
for(buf_i=0;buf_i<14;buf_i++){
int buf_len=bufsizeSet[buf_i];
char *buf=(char *)calloc(buf_len,sizeof(char));
int i=0;
for(i=0;i<buf_len;i++)
{
buf[i]='a' + rand()%26;
}
buf[buf_len]='\0';
struct msghdr msg;
bzero(&msg,sizeof(struct msghdr));
//msg.msg_name = NULL;
msg.msg_name = &their_addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
struct iovec io[4];
io[0].iov_base = buf;
io[0].iov_len = buf_len;
io[1].iov_base = buf;
io[1].iov_len = buf_len;
io[2].iov_base = buf;
io[2].iov_len = buf_len;
io[3].iov_base = buf;
io[3].iov_len = buf_len; msg.msg_iov = io;
msg.msg_iovlen =4;
int recycle_i=0;
for(recycle_i=8;recycle_i<9;recycle_i++){
int recycle_times=recycleSet[recycle_i];
struct timeval start_time,end_time;
gettimeofday(&start_time,NULL);
uint64_t start=rte_rdtsc();
for(i=0;i<recycle_times;i++)
{ //numbytes = send(sockfd, buf, strlen(buf), 0);MSG_DONTWAIT
numbytes = sendmsg(sockfd, &msg, 0);
//numbytes=recv(sockfd,buf,BUFSIZ,0);
//buf[numbytes]='\0';
//printf("send:%d\n",numbytes);
}
uint64_t end=rte_rdtsc();
//end_time=clock();
gettimeofday(&end_time,NULL);
uint64_t duration=end-start;
double duration_time=1000000*(end_time.tv_sec-start_time.tv_sec)+(end_time.tv_usec-start_time.tv_usec);
//printf("recycle_times=%d duration=%f numbytes=%d duration_rte=%f\n",recycle_times,duration_time,numbytes,duration/2.2);
printf("%d,%d,%d, %f ,%f,%f\n",recycle_times,numbytes,buf_len,duration_time,duration/2.3,duration_time*1.0/recycle_times);
}
}
close(sockfd);
return 0;
}

  客户端:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
/************************************************************************************************************************
1、int socket(int family,int type,int protocol)
family:
指定使用的协议簇:AF_INET(IPv4) AF_INET6(IPv6) AF_LOCAL(UNIX协议) AF_ROUTE(路由套接字) AF_KEY(秘钥套接字)
type:
指定使用的套接字的类型:SOCK_STREAM(字节流套接字) SOCK_DGRAM
protocol:
如果套接字类型不是原始套接字,那么这个参数就为0
2、int bind(int sockfd, struct sockaddr *myaddr, int addrlen)
sockfd:
socket函数返回的套接字描述符
myaddr:
是指向本地IP地址的结构体指针
myaddrlen:
结构长度
struct sockaddr{
unsigned short sa_family; //通信协议类型族AF_xx
char sa_data[14]; //14字节协议地址,包含该socket的IP地址和端口号
};
struct sockaddr_in{
short int sin_family; //通信协议类型族
unsigned short int sin_port; //端口号
struct in_addr sin_addr; //IP地址
unsigned char si_zero[8]; //填充0以保持与sockaddr结构的长度相同
};
3、int connect(int sockfd,const struct sockaddr *serv_addr,socklen_t addrlen)
sockfd:
socket函数返回套接字描述符
serv_addr:
服务器IP地址结构指针
addrlen:
结构体指针的长度
4、int listen(int sockfd, int backlog)
sockfd:
socket函数绑定bind后套接字描述符
backlog:
设置可连接客户端的最大连接个数,当有多个客户端向服务器请求时,收到此值的影响。默认值20
5、int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen)
sockfd:
socket函数经过listen后套接字描述符
cliaddr:
客户端套接字接口地址结构
addrlen:
客户端地址结构长度
6、int send(int sockfd, const void *msg,int len,int flags)
7、int recv(int sockfd, void *buf,int len,unsigned int flags)
sockfd:
socket函数的套接字描述符
msg:
发送数据的指针
buf:
存放接收数据的缓冲区
len:
数据的长度,把flags设置为0
*************************************************************************************************************************/
int main(int argc, char *argv[])
{
int fd, new_fd, struct_len, numbytes,i;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buff[BUFSIZ*10];
printf("BUFFSIZE %d\n",BUFSIZ);
//struct msghdr msg;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(9999);
server_addr.sin_addr.s_addr = INADDR_ANY;
// bzero(&(server_addr.sin_zero), 8);
struct_len = sizeof(struct sockaddr_in);
while((fd = socket(AF_INET,SOCK_DGRAM,0)) == -1);
if (bind(fd, (struct sockaddr*)(&server_addr), struct_len) < 0)
{
printf("bind error\n");
return -1;
}
printf("Bind Success!\n");
// fd = socket(AF_INET, SOCK_DGRAM, 0);
/*while(bind(fd, (struct sockaddr *)&server_addr, struct_len) == -1);
printf("Bind Success!\n");
while(listen(fd, 100) == -1);
printf("Listening....\n");
printf("Ready for Accept,Waitting...\n");
new_fd = accept(fd, (struct sockaddr *)&client_addr, &struct_len);
*/
//printf("Get the Client.\n");
// numbytes = send(new_fd,"Welcome to my server\n",21,0);
int cnt=0;
while(1)
{
printf("recemsg\n");
struct msghdr msg;
bzero(&msg,sizeof(struct msghdr));
msg.msg_name =&client_addr;
msg.msg_namelen =sizeof(struct sockaddr_in);
struct iovec io;
io.iov_base =buff;
io.iov_len =BUFSIZ*100;
msg.msg_iov = &io;
msg.msg_iovlen = 5;
numbytes = recvmsg(fd,&msg,0);
char * temp = msg.msg_iov[0].iov_base;//获取得到的数据
temp[numbytes] = '\0';//为数据末尾添加结束符
// printf("get %d message:%s", numbytes,temp);
if(numbytes>0)
cnt++;
printf("get %d cnt %d\n", numbytes,cnt);
}
// close(new_fd);
close(fd);
return 0;
}

  

6,send测试数据表

7,sendmsg测试数据表(iovlen=1)

7,sendmsg测试数据表(iovlen=4)

8,比较send,sendmsg(iovlen=1),sendmsg(iovlen=4)

 9,用gettimeofday测试性能基本逻辑(gettimeofday和滴答数转化成时间基本差不多)

单位为:微秒

struct timeval start_time,end_time;
gettimeofday(&start_time,NULL);
uint64_t start=rte_rdtsc();

函数调用

uint64_t end=rte_rdtsc();
//end_time=clock();
gettimeofday(&end_time,NULL);
uint64_t duration=end-start;
double duration_time=1000000*(end_time.tv_sec-start_time.tv_sec)+(end_time.tv_usec-start_time.tv_usec);

8,send和sendmsg性能测试比较(循环一千万次,算出一次时间开销(微秒))

结论:

1,send和sendmsg的性能基本一样

2,性能随字节成正比,比如128B~1.55微秒 ,256B~2.57微秒,1024B~8.72微秒,4096B~34.22微秒

3,sendmsg(iovlen=1)和sendmsg(iovlen=4)的在发送相同字节情况下,性能也是4倍,sendmsg在性能上并没得到优化

send和sendmsg性能测试的更多相关文章

  1. send和sendmsg性能测试【sendmsg和send的性能基本一样,并没有得到优化】

    1,摘要:测试send和sendmsg的性能,影响这两个函数性能的因素主要有发送的字节大小,增加循环次数,从100到10000000(千万)减少计算误差 2,基本信息cat /proc/cpuinfo ...

  2. send, sendto, sendmsg - 从套接字发送消息

    概述 #include <sys/types.h> #include <sys/socket.h> int send(int s, const void *msg, size_ ...

  3. Man——send(2)翻译

    ##纯手打 Man——send(2) -->NAME: send, sendto, sendmsg - 在socket上发送一条消息 -->总览: #include <sys/typ ...

  4. 一文彻底搞通TCP之send & recv原理

    接触过网络开发的人,大抵都知道,上层应用使用send函数发送数据,使用recv来接收数据,而send和recv的实现原理又是怎样的呢? 在前面的几篇文章中,我们有提过,TCP是个可靠的.全双工协议.其 ...

  5. jee websocket搭建总结

    1.使用框架spring+springmvc+mybatis+jdk7+tomcat7+maven 2.基本原理: a. WebSocket协议是一种双向通信协议,它建立在TCP之上,同http一样通 ...

  6. javaScript AJAX

    AJAX的实现 var sAjax = function () { var sendMsg = { url: "", sendType: "POST", Con ...

  7. Socket网络编程-基础篇

    Socket网络编程 网络通讯三要素: IP地址[主机名] 网络中设备的标识 本地回环地址:127.0.0.1 主机名:localhost 端口号 用于标识进程的逻辑地址 有效端口:0~65535 其 ...

  8. (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  9. [16]APUE:套接字

    [a] socket / socketpair #include <sys/socket.h> int socket(int domain, int type, int protocol) ...

随机推荐

  1. jqgrid 宽度自适应

    当jqgrid所在操作区宽度大于了给各列设置宽度之和时,此时表格的宽度未铺满操作区,效果不理想 此时,可以通过配置宽带自适应来现实表格内容自动铺满. 配置属性 shrinkToFit:ture 若要启 ...

  2. VS一些快捷键

    参考网址:http://www.open-open.com/lib/view/open1412261028453.html (这里省去了很多大家闭上眼都会操作的什么Ctrl+S 等等操作 给出的大多是 ...

  3. 数据结构与算法 基于c语言篇

    学习数据结构与算法走向深蓝之路 第一章:数据结构与算法概念型 数据结构:数据之间的相互关系,即是数据的组织形式. 基本组成:{ 数据:信息的载体 数据元素:数据基本单位: } 其结构形式有四种: 1, ...

  4. 【服务器】Https服务配置

    1)利用openssl生成证书 2)再次修改nginx配置文件nginx.conf中的server配置 ① 是默认监听http请求的8080端口的 server    (再次修改,第一次是在 用ngi ...

  5. 1.6《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——小结

    本章节学过的重要命令整理,见下表Table 2. 命令 描述 例子 echo <string> 向屏幕输出字符串 $ echo hello man <command> 显示命令 ...

  6. Patchwork(2013年)--CNV检测方法流程

    文章题目:Patchwork: allele-specific copy number analysis of whole-genome sequenced tumor tissue 特点: 可以检测 ...

  7. 20155226《网络攻防》 Exp5 MSF基础应用

    20155226<网络攻防> Exp5 MSF基础应用 基础问题回答 1.用自己的话解释什么是exploit,payload,encode? exploit : Exploit的英文意思就 ...

  8. EZ 2018 04 13 NOIP2018 模拟赛(八)

    这次的题目都是什么鬼? 玄学乱搞+肉眼看CODE+倒着搜索? 好吧是我ZZ了 链接在此 T1 玄学乱搞 由于考场上写的部分分做法忘记讨论n<=2000时的情况,少得了30pts 很容易得到一个基 ...

  9. [清华集训2015 Day1]主旋律-[状压dp+容斥]

    Description Solution f[i]表示状态i所代表的点构成的强连通图方案数. g[i]表示状态i所代表的的点形成奇数个强连通图的方案数-偶数个强连通图的方案数. g是用来容斥的. 先用 ...

  10. 汇编 REPNE/REPNZ指令,SCASW指令,SCASD指令,SCAS指令

    知识点: REPNE/REPNZ 指令 SCASW 指令 SCASD 指令 SCAS 指令 一.SCASW 指令 //SCASB cmp word ptr [edi],al //对标志位的影响 ...