I. Similarities and Differences between iocp and epoll.
Differences:
1: iocp is used in windows. Epoll is used in Linux.
2: iocp is an event notification completed by the get function after I/O operations are completed.
Epoll is used to query epoll for readability or writability when you want to perform an IO operation. If epoll is in the readable or writeable state, epoll will notify you through epoll_wait.
3: iocp encapsulates the asynchronous notification mechanism for message events and some IO operations. However, epoll only encapsulates an asynchronous event notification mechanism and is not responsible for Io read/write operations. Epoll maintains the independence between Event Notifications and IO operations, making it simpler and more flexible.
4: Based on the above description, we can know that epoll is not responsible for Io operations, so it only tells you that it is currently readable and writable, and fills in the Protocol read/write buffer, which is controlled by users, in this case, we can perform many additional operations. Iocp directly notifies the user after all the read and write operations in the IO channel are completed. When there is a blockage in the IO channel, we cannot control it. Same:
1: they are all asynchronous event-driven network models.
2: both of them can transmit pointer data to the underlying layer. When an event is returned, in addition to the event type, event-related data can be notified. Ii. Description: iocp:
Stay away. First, the network I/O Process of traditional servers is as follows:
Connect to a client connection-> Create a thread to take charge of the I/O operations of the connection-> continuously process data for the new thread-> complete data processing-> terminate the thread.
However, the design cost is:
1: Creating a thread for each connection will lead to too many threads.
2: The stack memory consumed by the maintenance thread is too large.
3: the operating system creation and destruction threads are too large.
4: the context price for switching between threads is too high.
In this case, we can consider using the thread pool to Solve the Problems 3 and 4. This traditional server network structure is called the session model.
Later, we created an I/O model to prevent the maintenance of a large number of threads. It was expected:
1: allows a thread to serve multiple clients at different times.
2: Allow a client to be served by multiple threads at different times.
In this way, our threads will be greatly reduced, which requires the following two points:
1: separation of client status. We can know the client status through the thread status in the previous session mode, but now the client status needs to be obtained through other methods.
2: separation of I/O requests. If a thread no longer serves a Client Session, the client must submit an I/O Processing request to this thread.
The following model is created:
1: session Status management module. It is responsible for receiving a client connection and creating a session status.
2: when the session status changes, such as disconnected connections and network messages are received, an I/O request is sent to the I/O module for processing.
3: After the I/O module receives an I/O request, it wakes up a working thread from the thread pool and asks the Working thread to process the I/O request. After the processing, the worker thread continues to be suspended.
In the above practice, the network connection and the I/O working thread are separated into two parts, and mutual communication only relies on I/O requests.
The following suggestions are available:
1: The worker thread for processing I/O requests is a wake-up worker thread. If one CPU corresponds to the other, the CPU can be used to the maximum extent. Therefore, the number of active threads is recommended to be equal to the number of hardware CPUs.
2: We started to create a thread pool for working threads, avoiding the cost of creating and destroying threads. Because threads operate on I/O and correspond to each other one by one, when I/O is fully parallel, the working thread must meet the requirements for parallel I/O operations, therefore, we recommend that the maximum number of working threads in the thread pool be greater than or equal to the number of parallel I/O threads.
3: however, we know that the number of CPUs limits the number of active threads, so the thread pool is too large, so it is recommended that the thread pool size be equal to the number of CPUs * 2. For example, we recommend that you create a thread pool of 16 worker threads for an 8-core server.
The I/O model is not iocp, so what is iocp? The full name is the I/O completion port.
It is a Win32 network I/O model, which includes both network connection and I/O operations, it is used to control concurrency network I/O operations. It has the following features:
1: it is a Win32 kernel object, so it cannot run in Linux.
2: it maintains the working thread pool and the memory pool of the I/O channel.
3: it implements thread management and I/O Request notifications by itself, minimizing thread context switching.
4: It optimizes Thread Scheduling and improves CPU and memory buffer usage.
The basic steps for using iocp are simple:
1: Create an iocp object that is responsible for managing multiple sockets and I/O requests. Createiocompletionport needs to bind the iocp object to the iocp handle.
2: Create a worker thread pool so that after the socket sends an I/O Request to the iocp object, these worker threads perform I/O operations. Note: When creating these threads, bind these threads to the iocp.
3: Create a listener socket.
4: Round Robin. When a new connection is received, the socket and the completion port are associated and delivered to the iocp for an I/O Request. Note: The functions associated with socket and iocp are the same as those created for iocp. They are both createiocompletionport, but note that passing parameters is different.
5: because it is asynchronous, we can do anything else. When iocp completes the I/O operation, it will return a message to us and then process it.
You need to know that I/O requests are placed in an I/O Request queue, which is a queue and a LIFO mechanism. After a device processes an I/O request, it will return the completed I/O Request to the iocp I/O Completion queue.
Our application needs to query iocp in getqueuedcompletionstatus to check whether the I/O request is complete.
There are some special things to explain. Sometimes we need to manually deliver some I/O requests, you need to use the postqueuedcompletionstatus function to deliver an I/O Request to iocp to its request queue.
Iii. Considerations and Optimization Measures for online game servers
1: Io operations are the biggest performance consumption point. There is a lot of room for optimization.
2: algorithm data structure. Optimization of sorting and finding algorithms. List, vector, and hashmap options. Big Data addressing. do not consider traversal. Consider hash.
3: memory management. Reload the processing of new/delete, memory pool, and Object pool.
4: data preparation and real-time computing.
5: Statistical monitoring on CPU. Logical frame count (within 50 ms ).
6: pre-allocated pools reduce switching and scheduling, pre-processing thread pools and connection pools.
7: monitoring framework for Statistics and Information of the basic and message queues.
8: CPU consumption ranking: The first AOI synchronization, the second network packet sending I/O operations, the third skill/buff judgment calculation and processing, and the fourth timer frequency.
9: detects memory leaks, detects out-of-bounds memory access, and recycles memory fragments.
10: memory consumption ranking: the first player object includes its items and the second network data buffer.
11: Pay attention to 32-bit and 64-Bit Memory fault tolerance.
12: Reduce Unnecessary packet sending.
13: reduce the cost of duplicate and duplicate packages.
14: it is recommended to divide the emergency package (send immediately) and non-emergency package (send regularly ).
15: Ranking of bandwidth consumption: synchronization of the first mobile location, loading of the second object, burst package of the third login, and timer message of the fourth state machine.
16: some pre-judgment mechanisms can be implemented on the client, and some operations should be forwarded as much as possible.
17: when a large number of players gather, some non-emergency packets are discarded.
18: Pay attention to the number of keys in a single database table.
19: separated access processing for active and non-active users.
20: control the operation frequency of gamer operations on the database.
21: use shared memory to securely back up and store data.
22: Pay attention to the security policy. Check the Intranet IP address and record the logs. It is better to use the encryption algorithm in any two ring points.
23: monitor and control the gateway, database, and other interfaces in real time.
24: The timer should store a queue instead of one-way positioning.
25: During data synchronization, you do not need to synchronize the data directly. You can add an AOI to the role. Based on the round-square collision principle, You can discard unnecessary grid information and save a lot of money.
26: The client performs partial prediction. Pay attention to the timestamp during server detection.
27: regular heartbeat packets. It is necessary to check dead links.
28: in order to be more responsible for various types of AI, AI independent server design is already necessary. The second thing to consider is chat and synchronization.
29: UDP can be used between the Intranet and the server.
30: Pay attention to the dynamic expansion and allocation of all memory pools and object pools.
1: The concept of exchanging memory for CPU.
2: the idea that the NPC is not dead. (Disable only)
3: The concept of Dynamic Scaling and Server Load balancer.
4: the client is untrusted.
5: pointer data, messages are untrusted. |