Delphi-Cross-Socket icon indicating copy to clipboard operation
Delphi-Cross-Socket copied to clipboard

提高性能

Open HeZiHang opened this issue 6 years ago • 10 comments

很高兴你的程序质量有大幅提升,不仅使用了很多Delphi的新语法,如匿名函数、泛型、并行库等,而且还重构了代码,采用面向接口的编程,更方便使用和扩张,同时更好的防止内存泄漏。

为了得到更高的性能,希望作者能有更多改进: 1.每个线程有自己独立的完成端口(消息队列),不访问其他线程的完成端口。不像现在每个Server都创建完成端口,而是每次启动时就固定创建好CPU个线程和完成端口。每个TCP连接或者相关的TCP连接,只由此线程处理。这样可以不用处理粘包,避免IO乱序(单Socket大量包时后到的io先被处理)问题,可以大量避免锁的使用,性能得到提升。 2.在改进第1步基础上,可再进一步改进:建立CPU亲和性,每个CPU运行一个工作线程,每个线程建立独立的内存管理器,线程启动时申请大块内存,由线程的内存管理器分配内存。

HeZiHang avatar Apr 05 '18 14:04 HeZiHang

楼上的意思是创建多个IoHandle独立处理吗?

pony5551 avatar Apr 07 '18 00:04 pony5551

影响CPU性能的关键在于:1.锁的大量使用,2.内核用户态之间上下文切换,3.大量CPU硬件中断响应,4.多核内存访问瓶颈 1.目前架构是1个iocp,由n个线程处理io,需要有大量的锁(包括原子操作)来处理,CPU的花费大量时间在等待中。因此,如果n个线程各有各的iocp,即n个CPU有n个线程,每个线程有各自的iocp,这样各线程处理自己的io,各io不与其他线程相关,则可以不用锁,可以大大减少锁的使用,极大提高性能。 2.每个线程可以绑定在一个CPU核上运行,不会被调度到其他CPU,这样能够进一步提高效率。 3.如果每个CPU有独立的物理内存,那么就可以减少内存访问时间,提高效率。这个需要CPU支持NUMA架构。还不清楚Windows是否支持Numa。但我们可以先为每个线程提供独立的内存。 3.由于内存管理器中是线程安全,所以里面也有很多锁的存在,因此如果每个线程处理自己的io,那么如果每个线程有自己的内存管理器,或者是每个线程有自己的内存池不用内存管理器,那么还能进一步提升性能。 4.如果需要进一步性能,需要在用户态(Ring3)中进行硬件(网卡)操作,绕开CPU的中断及内核用户态切换的花销。这个Windows可能做不到,但可以通过驱动程序提供硬件访问,由用户态进行网卡操作。 5.如果所有的这些优化措施都能做到,可以单机性能到百万级别并发。(可百度dptk)

HeZiHang avatar Apr 07 '18 03:04 HeZiHang

由于Delphi-Cross-Socket中使用的默认内存管理器,而且里面大量使用了String,Delphi的String是需要经常进行内存申请和释放操作,因此如果多个线程不停的使用不定长度的String,时间长了,可能会造成大量碎片内存。

HeZiHang avatar Apr 07 '18 04:04 HeZiHang

楼上说的让我学习了,之前一直认为只能用一个io能处理,看来网上流传的无锁iocp是真的,就是不知道kqueue和epoll能不能也这样用

pony5551 avatar Apr 07 '18 05:04 pony5551

都可以。

HeZiHang avatar Apr 07 '18 13:04 HeZiHang

很好的建议,不过相关的修改需要耗费不少精力,现在暂时没有这么大块的时间。 不过你如果有时间帮忙按你建议这几条完善这套库的话,欢迎之至 :)

winddriver avatar Apr 09 '18 03:04 winddriver

@HeZiHang @winddriver 建议子航修改一个版本,这样我们也能学到不少东西

pony5551 avatar Apr 09 '18 04:04 pony5551

其实现在性能已经基本够了,没有必要单机处理大并发,集群比较好

joestarzxh avatar Apr 10 '18 01:04 joestarzxh

@winddriver 我最近也没有大块时间,我们可以慢慢来,定义一个路线图。 比如: 1.建立2.0分支版本, 2.定义一个新的内存管理器,各线程独立的内存管理。 3.定义无锁循环队列,用于线程间发送消息,传递数据。 4.定义一个线程变量模型,可参考Spring中的线程变量 5.修改为每个线程对应一个io队列。

HeZiHang avatar Apr 10 '18 02:04 HeZiHang

@HeZiHang 我创建了一个develop分支,你可以fork之后在这个分支上开发

winddriver avatar Apr 10 '18 03:04 winddriver