Introduction
As modern processors contain millions of elements on small crystal, and personal computers are not equipped by industrial cooling systems, the problem of overheated CPUs rises sharply.
It is possible to determine experimentally, that by sequential calls of about 4000 standard transcendental math functions, for which operating time occupies no more than 1 second, it is possible to overheat processor, to disabled condition.
Concepts
One decision of the given problem, quantisation of threads on such quantity of processor instructions, does not lead to processor overheat. It is this obvious, that thread of instructions that guarantee absence of processor overheat, should not be out of more than 1 second and contain, no more than 1 million executing instructions of processor and coprocessor.
That to follow by given solution scheme, of overheat processor problem, is necessary to correctly make functional decomposition of computing algorithm, to processor threads which are carried out, by default in a parallel way, even they are required, to be started consequently.
Background
Most widespread cases of presence of such problems are difficult mathematical calculations, but also it is needed to notice that for display received even by trivial, from point of view of processor loading, results in a graphic way, a lot of mathematical calculations are required.
Using the Code
For example, let us consider the algorithm that tests accuracy and speed of mathematical coprocessor, with creation of hypertext report file, and displays it in Internet browser.
From the beginning, it is possible to say that for each action, it is needed to create a separate thread of instructions, but as a result arises a question — how to count loading of processor in each thread. And of course, it could be done by counting instructions in thread — but more reasonable, is an experimental way, assuming testing of code in the presence of overloading processor threads in code debugger.
Therefore, we will return to the chosen example, and will call two main threads, consequently creating and displaying report file. Thus, for maintenance of consequential execution of threads, one mutex is required:
thrd_t thr;
static mtx_t report;
mtx_init(&report, mtx_plain);
thrd_create(&thr, (thrd_start_t)createReportHTM, szFile);
thrd_create(&thr, (thrd_start_t)showReportHTM, szFile);
Also, consider the realization of given functions:
void createReportHTM (TCHAR *filename) { createReport(filename, true); mtx_unlock(&report); };
void showReportHTM (TCHAR *filename) {
timespec_t ts = { 1, 0 };
if (mtx_lock(&report) != thrd_success) return;
while (thrd_sleep(&ts, &ts));
showHTM(filename);
mtx_destroy(&report);
};
Pay attention that to delaying, in the second thread thrd_sleep
function is used — in general use it, it is not necessary, but if we were to assume that previous thread during last second completely loaded processor, for compensating this loading — there is a need, for more reliability to give second “for free” processor.
Further, in program should be made overloading testing of coprocessor, which is more reasonable divide on more smaller threads — therefore, it is needed to store all data in local variable record, in function stack that creates full report, and this function thread must wait ending, writing report thread — as this thread expects data, to be actual during execution.
In this case, for maintenance of sequential execution of threads, that writing file and unknown quantity of testing threads, it is better to use mutex in variable containing quantity of started threads of program module:
typedef struct {
unsigned char use;
unsigned min_exact, mid_exact, max_exact;
mace min_accuracy, mid_accuracy, max_accuracy;
} ReportAccuracyData;
typedef struct {
unsigned char n;
unsigned long time, flops, cycles;
ReportAccuracyData flt, dbl, ldbl;
} ReportCoreData;
typedef struct {
TCHAR *filename;
ReportCoreData core[32];
} ReportData;
static short cooler;
Further, we will consider text of function, organising work of report file threads (insignificant part of code is lowered).
void createReport (TCHAR *filename) {
byte i;
thrd_t thr;
ReportData data = { filename };
memset(&data, 0, sizeof(data));
cooler = 0;
for (i = 0; i < 32; i++)
cooler++;
thrd_create(&thr, (thrd_start_t)createTimingData, &data.core[i]);
cooler++;
thrd_create(&thr, (thrd_start_t)createAccuracyData, &data.core[i].flt);
cooler++;
thrd_create(&thr, (thrd_start_t)createAccuracyData, &data.core[i].dbl);
cooler++;
thrd_create(&thr, (thrd_start_t)createAccuracyData, &data.core[i].ldbl);
};
cooler++;
thrd_create(&thr, (thrd_start_t)createReportFile, &data);
while (cooler) thrd_yield();
};
Text one of testing functions (insignificant part of code is lowered):
void createAccuracyData (ReportAccuracyData *data) {
timespec_t ts = { 1, 0 };
while (thrd_sleep(&ts, &ts));
cooler--;
};
And text of function, writing report file (insignificant part of code is lowered):
void createReportFile (ReportData *data) {
while (cooler > 1) thrd_yield();
cooler--;
};
Points of Interest
Apparently from the given example, it is seen that basic methods are used for organisation multitasking programs. There are two kinds of mutexes — report
and cooler
, and accordingly two ways of expectation resources that are needed for threads — mtx_lock
and thrd_yield
, considering the absence or necessity for quantization overheating algorithms on smaller parts.