CPUs Maximum Throughput and Overhead

From Scriptionary.com

Jump to: navigation, search
Author Eddy Luten
Author Link Scriptionary.com
Contributors none so far
Notes
Article was recovered form cached search engine result, might contain bad formatting. Uses deprecated RDTSC instructions, use at your own risk

This is another article recovered from search engine results, this time on the topic of RDTSC. Beware that RDTSC is not accurate on multi-core machines.


Contents


About Throughout

Throughput is the amount of data a CPU (or any other device) can process in a certain amount of time from one point to another.

Maximum Throughput is the amount of data that the CPU is able to process without any latency by interfering processes.

Calculation

Calculating the Maximum Throughput for a CPU is relatively easy. Let's assume that there is a 33MHz CPU operating on a 32 bits wide bus.

To calculate the Maximum Throughput in bytes we use the following equation:

T = (W/8) * (S*1,000,000)

Where T equals maximum throughput, W equals bus width and S equals bus speed in MHz.

So for a 32 bits CPU running at 33MHz the solution would be 1.32E+8 Bytes per second. This would mean that a 33 MHz CPU would be able to process more than 125.8 megabytes per second.

Overhead

The equation above might be accurate to a certain extent but in reality the number might drop a bit. There is no precise way of determining CPU overhead but there are certain calculations you can perform to somewhat calculate the CPU overhead. On modern processors (Pentium 2 and up) a new instruction was added to the x86 processor platform, namely: RDTSC.

The Code

RDTSC is a processor function which returns the amount of ticks since processor reset. The data type returned is 64 bits unsigned.

To return the value of RDTSC we use the following mix of C and inline assembly.

unsigned long long RDTSC( void ){
	__asm rdtsc __asm rdtsc; //warm up
	__asm{
		rdtsc;
	};
};

Syntax for your specific compiler might differ since the samples provided were done in Microsoft Visual C/C++. To calculate how much time it takes to get from instruction to instruction (overhead) we simply calculate:

int overhead = (int) ( RDTSC() - RDTSC() ) * (-1);

Since the subtraction of a low number with a high number results in a negative number we have to convert the number into a positive by multiplying the result with negative 1.

Variable overhead now holds the amount of ticks it took to get from the first RDTSC call to the second. Usually this ranges around 50-400 ticks depending on how CPU dependent your system is at the moment.

In this document, I'll assume 200 ticks overhead. To convert this number into a real second-based number we need to attain the CPU’s clock speed.

One way of achieving this is by calling the following function which returns the CPU’s frequency in Hertz:

int GetCPUClock( void ){
	long long start = RDTSC();
	Sleep(1000); //1000 microseconds = 1 second
	return (int) ( RDTSC() - start ) / 1000000; 
};

The Sleep function might differ for your specific platform.

This means that if your CPU's frequency returns as 500,000,000 Hz (1 second), 200 Hz of overhead would be 4 1,000,000th of a second or 0.4 microseconds.

The C function for calculating this is:

long double ConvertOverhead (int overhead, int clock) {
	return (long double) overhead / clock * 1000000;
};

End Note The RDTSC functionality might not work properly on multi-core processors. Do not use RDTSC for timing anything; use Operating System specific API functions.

Also, the Sleep function puts the current thread asleep for one whole second, so if you want to call the GetCPUClock function, do it at program initialization only.

Putting all of the code together (you might have to reformat for your specific compiler):

#include <stdio.h>
 
#ifdef _WIN32 //Win32 specific:
#	define WIN32_LEAN_AND_MEAN
#	include <windows.h>
#else
//	include specific header for other OS'
#endif
 
unsigned long long RDTSC( void ){
	__asm rdtsc __asm rdtsc; //warm up
	__asm{
		rdtsc;
	};
};
 
int GetCPUClock( void ){
	long long start = RDTSC();
	Sleep(1000); //1000 microseconds = 1 second
	return (int) ( RDTSC() - start ); 
};
 
long double ConvertOverhead (int overhead, int clock) {
	return (long double) overhead / clock * 1000000;
};
 
int main(){
	int overhead = (int) ( RDTSC() - RDTSC() ) * (-1);
	int clock = GetCPUClock();
	long double overheadms = ConvertOverhead( overhead , clock );
	printf ("Measured CPU Ticks: %u\n", clock);
	printf ("Overhead in Ticks: %u\n", overhead);
	printf ("Overhead in ms: %Lf\n", overheadms );
	return 0;
};

The output might look a little like this:

Measured CPU Ticks: 1866542748
Overhead in ticks: 371
Overhead in ms: 0.198763
Personal tools