v2.6 +multi-threading

This commit is contained in:
alex
2015-06-09 19:54:38 +01:00
parent 2364bbf6b9
commit 523cb1e736
10 changed files with 309 additions and 230 deletions

View File

@@ -451,7 +451,7 @@ double saalos(double d, prop_type & prop, propa_type & propa)
double adiff(double d, prop_type & prop, propa_type & propa)
{
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
static double wd1, xd1, afo, qk, aht, xht;
static __thread double wd1, xd1, afo, qk, aht, xht;
double a, q, pk, ds, th, wa, ar, wd, adiffv;
if (d == 0) {
@@ -513,7 +513,7 @@ double adiff(double d, prop_type & prop, propa_type & propa)
double adiff2(double d, prop_type & prop, propa_type & propa)
{
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
static double wd1, xd1, qk, aht, xht, toh, toho, roh, roho, dto, dto1,
static __thread double wd1, xd1, qk, aht, xht, toh, toho, roh, roho, dto, dto1,
dtro, dro, dro2, drto, dtr, dhh1, dhh2, /* dhec, */ dtof, dto1f,
drof, dro2f;
double a, q, pk, rd, ds, dsl, /* dfdh, */ th, wa, /* ar, wd, sf1, */
@@ -829,7 +829,7 @@ double adiff2(double d, prop_type & prop, propa_type & propa)
double ascat(double d, prop_type & prop, propa_type & propa)
{
static double ad, rr, etq, h0s;
static __thread double ad, rr, etq, h0s;
double h0, r1, r2, z0, ss, et, ett, th, q;
double ascatv, temp;
@@ -954,7 +954,7 @@ void qlrps(double fmhz, double zsys, double en0, int ipol, double eps,
double alos(double d, prop_type & prop, propa_type & propa)
{
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
static double wls;
static __thread double wls;
complex < double >r;
double s, sps, q;
double alosv;
@@ -1146,8 +1146,8 @@ void qlra(int kst[], int klimx, int mdvarx, prop_type & prop,
void lrprop(double d, prop_type & prop, propa_type & propa)
{
/* PaulM_lrprop used for ITM */
static bool wlos, wscat;
static double dmin, xae;
static __thread bool wlos, wscat;
static __thread double dmin, xae;
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
double a0, a1, a2, a3, a4, a5, a6;
double d0, d1, d2, d3, d4, d5, d6;
@@ -1337,8 +1337,8 @@ void lrprop(double d, prop_type & prop, propa_type & propa)
void lrprop2(double d, prop_type & prop, propa_type & propa)
{
/* ITWOM_lrprop2 */
static bool wlos, wscat;
static double dmin, xae;
static __thread bool wlos, wscat;
static __thread double dmin, xae;
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
double pd1;
double a0, a1, a2, a3, a4, a5, a6, iw;
@@ -1612,8 +1612,8 @@ double curve(double const &c1, double const &c2, double const &x1,
double avar(double zzt, double zzl, double zzc, prop_type & prop,
propv_type & propv)
{
static int kdv;
static double dexa, de, vmd, vs0, sgl, sgtm, sgtp, sgtd, tgtd,
static __thread int kdv;
static __thread double dexa, de, vmd, vs0, sgl, sgtm, sgtp, sgtd, tgtd,
gm, gp, cv1, cv2, yv1, yv2, yv3, csm1, csm2, ysm1, ysm2,
ysm3, csp1, csp2, ysp1, ysp2, ysp3, csd1, zd, cfm1, cfm2,
cfm3, cfp1, cfp2, cfp3;
@@ -1650,7 +1650,7 @@ double avar(double zzt, double zzl, double zzc, prop_type & prop,
double bfp1[7] = { 1.0, 0.93, 1.0, 0.93, 0.93, 1.0, 1.0 };
double bfp2[7] = { 0.0, 0.31, 0.0, 0.19, 0.31, 0.0, 0.0 };
double bfp3[7] = { 0.0, 2.00, 0.0, 1.79, 2.00, 0.0, 0.0 };
static bool ws, w1;
static __thread bool ws, w1;
double rt = 7.8, rl = 24.0, avarv, q, vs, zt, zl, zc;
double sgt, yr, temp1, temp2;
int temp_klim = propv.klim - 1;
@@ -1974,6 +1974,7 @@ void z1sq1(double z[], const double &x1, const double &x2, double &z0,
xa = xb - xa;
x = -0.5 * xa;
xb += x;
a = 0.5 * (z[ja + 2] + z[jb + 2]);
b = 0.5 * (z[ja + 2] - z[jb + 2]) * x;

View File

@@ -1,8 +1,8 @@
#include <stdio.h>
#include <math.h>
#include "../common.h"
#include "../main.hh"
#include "los.hh"
#include "cost.hh"
#include "ecc33.hh"
#include "ericsson.hh"
@@ -10,6 +10,154 @@
#include "hata.hh"
#include "itwom3.0.hh"
#include "sui.hh"
#include <pthread.h>
#define MAXPAGES 64
#define IPPD 3600
#define NUM_SECTIONS 4
namespace {
pthread_t threads[NUM_SECTIONS];
unsigned int thread_count = 0;
pthread_mutex_t maskMutex;
bool processed[MAXPAGES][IPPD][IPPD];
bool has_init_processed = false;
struct propagationRange {
int min_west, max_west, min_north, max_north;
double altitude;
bool eastwest, los, use_threads;
site source;
unsigned char mask_value;
FILE *fd;
int propmodel, knifeedge, pmenv;
};
void* rangePropagation(void *parameters)
{
propagationRange *v = (propagationRange*)parameters;
if(v->use_threads) {
alloc_elev();
alloc_path();
}
double minwest = dpp + (double)v->min_west;
double lon = v->eastwest ? minwest : v->min_west;
double lat = v->min_north;
int y = 0;
do {
if (lon >= 360.0)
lon -= 360.0;
site edge;
edge.lat = lat;
edge.lon = lon;
edge.alt = v->altitude;
if(v->los)
PlotLOSPath(v->source, edge, v->mask_value, v->fd);
else
PlotPropPath(v->source, edge, v->mask_value, v->fd, v->propmodel,
v->knifeedge, v->pmenv);
++y;
if(v->eastwest)
lon = minwest + (dpp * (double)y);
else
lat = (double)v->min_north + (dpp * (double)y);
} while ( v->eastwest
? (LonDiff(lon, (double)v->max_west) <= 0.0)
: (lat < (double)v->max_north) );
if(v->use_threads) {
free_elev();
free_path();
}
return NULL;
}
void init_processed()
{
for(int i = 0; i < MAXPAGES; i++) {
for (int x = 0; x < ippd; x++) {
for (int y = 0; y < ippd; y++) {
processed[i][x][y] = false;
}
}
}
}
bool can_process(double lat, double lon)
{
/* Lines, text, markings, and coverage areas are stored in a
mask that is combined with topology data when topographic
maps are generated by ss. This function sets bits in
the mask based on the latitude and longitude of the area
pointed to. */
int x, y, indx;
char found;
bool rtn = false;
for (indx = 0, found = 0; indx < MAXPAGES && found == 0;) {
x = (int)rint(ppd * (lat - dem[indx].min_north));
y = mpi - (int)rint(ppd * (LonDiff(dem[indx].max_west, lon)));
if (x >= 0 && x <= mpi && y >= 0 && y <= mpi)
found = 1;
else
indx++;
}
if (found) {
/* As long as we only set this without resetting it we can
check outside a mutex first without worrying about race
conditions. But we must lock the mutex before updating the
value. */
if(!processed[indx][x][y]) {
pthread_mutex_lock(&maskMutex);
if(!processed[indx][x][y]) {
rtn = true;
processed[indx][x][y] = true;
}
pthread_mutex_unlock (&maskMutex);
}
}
return rtn;
}
void beginThread(void *arg)
{
if(!has_init_processed)
init_processed();
int rc = pthread_create(&threads[thread_count], NULL, rangePropagation, arg);
if (rc)
printf("ERROR; return code from pthread_create() is %d\n", rc);
else
++thread_count;
}
void finishThreads()
{
void* status;
for(unsigned int i=0; i<thread_count; i++) {
int rc = pthread_join(threads[i], &status);
if (rc)
printf("ERROR; return code from pthread_join() is %d\n", rc);
}
thread_count = 0;
}
}
/*
* Acute Angle from Rx point to an obstacle of height (opp) and
@@ -89,7 +237,9 @@ void PlotLOSPath(struct site source, struct site destination, char mask_value,
/* Test this point only if it hasn't been already
tested and found to be free of obstructions. */
if ((GetMask(path.lat[y], path.lon[y]) & mask_value) == 0) {
if ((GetMask(path.lat[y], path.lon[y]) & mask_value) == 0
&& can_process(path.lat[y], path.lon[y])) {
distance = 5280.0 * path.distance[y];
tx_alt = earthradius + source.alt + path.elevation[0];
rx_alt =
@@ -183,8 +333,12 @@ void PlotPropPath(struct site source, struct site destination,
/* Process this point only if it
has not already been processed. */
if ((GetMask(path.lat[y], path.lon[y]) & 248) !=
(mask_value << 3)) {
if ( (GetMask(path.lat[y], path.lon[y]) & 248) !=
(mask_value << 3) && can_process(path.lat[y], path.lon[y])) {
char fd_buffer[64];
int buffer_offset = 0;
distance = 5280.0 * path.distance[y];
xmtr_alt =
four_thirds_earth + source.alt + path.elevation[0];
@@ -337,6 +491,7 @@ void PlotPropPath(struct site source, struct site destination,
destination.alt *
METERS_PER_FOOT, LR.eps_dielect,
LR.sgm_conductivity,
LR.eno_ns_surfref, LR.frq_mhz,
LR.radio_climate, LR.pol,
LR.conf, LR.rel, loss, strmode,
@@ -364,7 +519,7 @@ void PlotPropPath(struct site source, struct site destination,
loss, strmode, errnum);
}
if (knifeedge == 1) {
diffloss =
ked(LR.frq_mhz,
@@ -379,7 +534,8 @@ void PlotPropPath(struct site source, struct site destination,
azimuth = (Azimuth(source, temp));
if (fd != NULL)
fprintf(fd, "%.7f, %.7f, %.3f, %.3f, ",
buffer_offset += sprintf(fd_buffer+buffer_offset,
"%.7f, %.7f, %.3f, %.3f, ",
path.lat[y], path.lon[y], azimuth,
elevation);
@@ -388,7 +544,8 @@ void PlotPropPath(struct site source, struct site destination,
or received power level (below), as appropriate. */
if (fd != NULL && LR.erp == 0.0)
fprintf(fd, "%.2f", loss);
buffer_offset += sprintf(fd_buffer+buffer_offset,
"%.2f", loss);
/* Integrate the antenna's radiation
pattern into the overall path loss. */
@@ -418,7 +575,8 @@ void PlotPropPath(struct site source, struct site destination,
dBm = 10.0 * (log10(rxp * 1000.0));
if (fd != NULL)
fprintf(fd, "%.3f", dBm);
buffer_offset += sprintf(fd_buffer+buffer_offset,
"%.3f", dBm);
/* Scale roughly between 0 and 255 */
@@ -466,7 +624,8 @@ void PlotPropPath(struct site source, struct site destination,
(unsigned char)ifs);
if (fd != NULL)
fprintf(fd, "%.3f",
buffer_offset += sprintf(fd_buffer+buffer_offset,
"%.3f",
field_strength);
}
}
@@ -476,7 +635,7 @@ void PlotPropPath(struct site source, struct site destination,
ifs = 255;
else
ifs = (int)rint(loss);
ofs = GetSignal(path.lat[y], path.lon[y]);
if (ofs < ifs && ofs != 0)
@@ -488,9 +647,9 @@ void PlotPropPath(struct site source, struct site destination,
if (fd != NULL) {
if (block)
fprintf(fd, " *");
fprintf(fd, "\n");
buffer_offset += sprintf(fd_buffer+buffer_offset,
" *");
fprintf(fd, "%s\n", fd_buffer);
}
/* Mark this point as having been analyzed */
@@ -503,7 +662,8 @@ void PlotPropPath(struct site source, struct site destination,
}
void PlotLOSMap(struct site source, double altitude, char *plo_filename)
void PlotLOSMap(struct site source, double altitude, char *plo_filename,
bool use_threads)
{
/* This function performs a 360 degree sweep around the
transmitter site (source location), and plots the
@@ -514,10 +674,7 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
of a topographic map when the WritePPM() function
is later invoked. */
int x, y, z;
struct site edge;
double lat, lon, minwest, maxnorth, th;
static unsigned char mask_value = 1;
static __thread unsigned char mask_value = 1;
FILE *fd = NULL;
if (plo_filename[0] != 0)
@@ -529,64 +686,44 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
max_west, min_west, max_north, min_north);
}
th = ppd / loops;
// Four sections start here
// Process north edge east/west, east edge north/south,
// south edge east/west, west edge north/south
int range_min_west[] = {min_west, min_west, min_west, max_west};
int range_min_north[] = {max_north, min_north, min_north, min_north};
int range_max_west[] = {max_west, min_west, max_west, max_west};
int range_max_north[] = {max_north, max_north, min_north, max_north};
propagationRange* r[NUM_SECTIONS];
z = (int)(th * ReduceAngle(max_west - min_west));
for(int i = 0; i < NUM_SECTIONS; ++i) {
propagationRange *range = new propagationRange;
r[i] = range;
range->los = true;
minwest = dpp + (double)min_west;
maxnorth = (double)max_north - dpp;
range->eastwest = (range_min_west[i] == range_max_west[i] ? false : true);
range->min_west = range_min_west[i];
range->max_west = range_max_west[i];
range->min_north = range_min_north[i];
range->max_north = range_max_north[i];
for (lon = minwest, x = 0, y = 0;
(LonDiff(lon, (double)max_west) <= 0.0);
y++, lon = minwest + (dpp * (double)y)) {
if (lon >= 360.0)
lon -= 360.0;
range->use_threads = use_threads;
range->altitude = altitude;
range->source = source;
range->mask_value = mask_value;
range->fd = fd;
edge.lat = max_north;
edge.lon = lon;
edge.alt = altitude;
PlotLOSPath(source, edge, mask_value, fd);
}
z = (int)(th * (double)(max_north - min_north));
for (lat = maxnorth, x = 0, y = 0; lat >= (double)min_north;
y++, lat = maxnorth - (dpp * (double)y)) {
edge.lat = lat;
edge.lon = min_west;
edge.alt = altitude;
PlotLOSPath(source, edge, mask_value, fd);
if(use_threads)
beginThread(range);
else
rangePropagation(range);
}
z = (int)(th * ReduceAngle(max_west - min_west));
for (lon = minwest, x = 0, y = 0;
(LonDiff(lon, (double)max_west) <= 0.0);
y++, lon = minwest + (dpp * (double)y)) {
if (lon >= 360.0)
lon -= 360.0;
edge.lat = min_north;
edge.lon = lon;
edge.alt = altitude;
PlotLOSPath(source, edge, mask_value, fd);
}
z = (int)(th * (double)(max_north - min_north));
for (lat = (double)min_north, x = 0, y = 0; lat < (double)max_north;
y++, lat = (double)min_north + (dpp * (double)y)) {
edge.lat = lat;
edge.lon = max_west;
edge.alt = altitude;
PlotLOSPath(source, edge, mask_value, fd);
if(use_threads)
finishThreads();
for(int i = 0; i < NUM_SECTIONS; ++i){
delete r[i];
}
switch (mask_value) {
@@ -603,21 +740,14 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
}
}
void PlotPropagation(struct site source, double altitude, char *plo_filename,
int propmodel, int knifeedge, int haf, int pmenv)
int propmodel, int knifeedge, int haf, int pmenv, bool
use_threads)
{
int y, z, count;
struct site edge;
double lat, lon, minwest, maxnorth, th;
unsigned char x;
static unsigned char mask_value = 1;
static __thread unsigned char mask_value = 1;
FILE *fd = NULL;
minwest = dpp + (double)min_west;
maxnorth = (double)max_north - dpp;
count = 0;
if (LR.erp == 0.0 && debug)
fprintf(stdout, "path loss");
else {
@@ -657,139 +787,57 @@ void PlotPropagation(struct site source, double altitude, char *plo_filename,
max_west, min_west, max_north, min_north);
}
th = ppd / loops;
// Four sections start here
// Process north edge east/west, east edge north/south,
// south edge east/west, west edge north/south
int range_min_west[] = {min_west, min_west, min_west, max_west};
int range_min_north[] = {max_north, min_north, min_north, min_north};
int range_max_west[] = {max_west, min_west, max_west, max_west};
int range_max_north[] = {max_north, max_north, min_north, max_north};
propagationRange* r[NUM_SECTIONS];
//S1
if (haf == 0 || haf == 1) {
z = (int)(th * ReduceAngle(max_west - min_west));
for(int i = 0; i < NUM_SECTIONS; ++i) {
propagationRange *range = new propagationRange;
r[i] = range;
range->los = false;
for (lon = minwest, x = 0, y = 0;
(LonDiff(lon, (double)max_west) <= 0.0);
y++, lon = minwest + (dpp * (double)y)) {
if (lon >= 360.0)
lon -= 360.0;
// Only process correct half
if((NUM_SECTIONS - i) <= (NUM_SECTIONS / 2) && haf == 1)
continue;
if((NUM_SECTIONS - i) > (NUM_SECTIONS / 2) && haf == 2)
continue;
edge.lat = max_north;
edge.lon = lon;
edge.alt = altitude;
PlotPropPath(source, edge, mask_value, fd, propmodel,
knifeedge, pmenv);
count++;
range->eastwest = (range_min_west[i] == range_max_west[i] ? false : true);
range->min_west = range_min_west[i];
range->max_west = range_max_west[i];
range->min_north = range_min_north[i];
range->max_north = range_max_north[i];
if (count == z) {
count = 0;
range->use_threads = use_threads;
range->altitude = altitude;
range->source = source;
range->mask_value = mask_value;
range->fd = fd;
range->propmodel = propmodel;
range->knifeedge = knifeedge;
range->pmenv = pmenv;
if (x == 3)
x = 0;
else
x++;
}
}
if(use_threads)
beginThread(range);
else
rangePropagation(range);
}
//S2
if (haf == 0 || haf == 1) {
count = 0;
if (debug) {
fprintf(stdout, "\n25%c to 50%c ", 37, 37);
fflush(stdout);
}
z = (int)(th * (double)(max_north - min_north));
for (lat = maxnorth, x = 0, y = 0; lat >= (double)min_north;
y++, lat = maxnorth - (dpp * (double)y)) {
edge.lat = lat;
edge.lon = min_west;
edge.alt = altitude;
PlotPropPath(source, edge, mask_value, fd, propmodel,
knifeedge, pmenv);
count++;
if (count == z) {
count = 0;
if (x == 3)
x = 0;
else
x++;
}
}
if(use_threads)
finishThreads();
for(int i = 0; i < NUM_SECTIONS; ++i){
delete r[i];
}
//S3
if (haf == 0 || haf == 2) {
count = 0;
if (debug) {
fprintf(stdout, "\n50%c to 75%c ", 37, 37);
fflush(stdout);
}
z = (int)(th * ReduceAngle(max_west - min_west));
for (lon = minwest, x = 0, y = 0;
(LonDiff(lon, (double)max_west) <= 0.0);
y++, lon = minwest + (dpp * (double)y)) {
if (lon >= 360.0)
lon -= 360.0;
edge.lat = min_north;
edge.lon = lon;
edge.alt = altitude;
PlotPropPath(source, edge, mask_value, fd, propmodel,
knifeedge, pmenv);
count++;
if (count == z) {
count = 0;
if (x == 3)
x = 0;
else
x++;
}
}
}
//S4
if (haf == 0 || haf == 2) {
count = 0;
if (debug) {
fprintf(stdout, "\n75%c to 100%c ", 37, 37);
fflush(stdout);
}
z = (int)(th * (double)(max_north - min_north));
for (lat = (double)min_north, x = 0, y = 0;
lat < (double)max_north;
y++, lat = (double)min_north + (dpp * (double)y)) {
edge.lat = lat;
edge.lon = max_west;
edge.alt = altitude;
PlotPropPath(source, edge, mask_value, fd, propmodel,
knifeedge, pmenv);
count++;
if (count == z) {
count = 0;
if (x == 3)
x = 0;
else
x++;
}
}
} //S4
if (fd != NULL)
if (fd != NULL)
fclose(fd);
if (mask_value < 30)

View File

@@ -10,9 +10,9 @@ void PlotLOSPath(struct site source, struct site destination, char mask_value,
void PlotPropPath(struct site source, struct site destination,
unsigned char mask_value, FILE * fd, int propmodel,
int knifeedge, int pmenv);
void PlotLOSMap(struct site source, double altitude, char *plo_filename);
void PlotLOSMap(struct site source, double altitude, char *plo_filename, bool use_threads);
void PlotPropagation(struct site source, double altitude, char *plo_filename,
int propmodel, int knifeedge, int haf, int pmenv);
int propmodel, int knifeedge, int haf, int pmenv, bool use_threads);
void PlotPath(struct site source, struct site destination, char mask_value);
#endif /* _LOS_HH_ */