The Voice Elements Platform can support up to 1000 ports on a single system, and we hope to be able to continue increasing our available port density. However, there are several variables that may impact your performance.
Choosing a System
There are a few key hardware components that you need to consider:
You will want to make sure you choose a network card that has checksum offloading. Most modern network interface cards have this feature, but it is important enough that you will want to make sure. When checksum offloading isn’t present on the NIC, it will use the CPU to calculate the checksum significantly impacting performance.
While most systems from the last several years can run HMP Elements; in order to achieve a higher density, you will want to consider a more powerful CPU. In our testing, we were able to run 1000 ports on a Core i5-750, which is a quad core running at 2.66 GHz. We also ran tests on faster hardware, and did not have any difficulty getting to 1000 ports..
8GB of memory is recommended for running more than 500 ports, although you likely won’t run into any trouble using just 4GB..
This special mode uses WinPCAP to send our traffic instead of Winsock. This results in reduced CPU usage. You will want to use this tutorial for setting up PCAP mode. PCAP Mode must be enabled to achieve port densities of 500 or more.
Increase the Thread Pool Count
To minimize the impact of starting threads on the fly, we instead use a thread pool to minimize the performance impact associated with starting new threads. We allow the user to specify the minimum and maximum number of threads. You will want to add the following settings to your VoiceElementsServer.exe.config. You will want to make sure you place it in the “VoiceElements.Properties.Settings” section:
<VoiceElements.Properties.Settings> <setting name="ThreadPoolMax" serializeAs="String"> <value>2500</value> </setting> <setting name="ThreadPoolMin" serializeAs="String"> <value>1500</value> </setting> </VoiceElements.Properties.Settings>
These settings will also need to be included in your Voice Elements application’s client configuration file. In for these settings to be recognized, the following (bolded) will also need to be included in the “configSections” area near the top of the file:
<configSections> <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=184.108.40.206, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <section name="VoiceElements.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=220.127.116.11, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> … </sectionGroup> </configSections>
Auto Release Channels Setting
This setting tells Voice Elements to automatically release channels when a phone call gets hung up. This setting prevents a situation in which the Channel has not been fully disposed by the client, and a new call comes in on that channel. This setting should be added to the VoiceElementsServer.exe.config:
<VoiceElements.Properties.Settings> <setting name="AutoReleaseChannels" serializeAs="String"> <value>True</value> </setting> </VoiceElements.Properties.Settings>
In order to get the highest density, there are several items you will want to review to make sure that your code is as efficient as possible.
Below is a list of common issues that people run into when looking to increase the performance of their applications. This is not meant as a complete list, but as suggestions for potential problem areas:
Are there any locations where you are looping to check the result of the thread?
- Looping in a thread to check the result of an operation can result in high CPU utilization if the thread doesn’t periodically yield.
- In high-density systems with many simultaneous calls, the impact of tight loops can be even greater.
Would it be possible to rewrite what you are trying to do with a Reset Event?
- Instead of polling for a particular status by looping, consider using a reset event (ManualResetEvent, for example). In this way, the thread yields its processing time until the reset event is signaled, allowing processing to proceed.
Are you using the Disconnect Event?
- The disconnect event in conjunction with ResetEvents is a very efficient way to handle disconnections.
- While there are several ways to monitor disconnects, we’ve found this pattern to be the most beneficial.
Is there anywhere that you are forcing a thread to sleep and not using a ResetEvent?
- When you put a thread to sleep, the thread will not wake up until the time specified.
- While this may be a small time period, it can impact your port density.
For example, let’s say you start an outbound thread, and monitor it using a while loop with a sleep of 2000 milliseconds.
- If the outbound channel resource hangs up, at the beginning of the sleep, it won’t be recognized until the sleep is over.
- In a system that uses all of it’s ports, this could prevent the port from being re-used as fast as it could be.
- By using a reset event, it signals immediately when the given condition occurs (such as a hangup).
Do you still have questions? If so, please contact Inventive Labs Technical Support.