129 lines
3.7 KiB
C
129 lines
3.7 KiB
C
/*************************************************************************/
|
|
/* */
|
|
/* Copyright (c) 1994 Stanford University */
|
|
/* */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* Permission is given to use, copy, and modify this software for any */
|
|
/* non-commercial purpose as long as this copyright notice is not */
|
|
/* removed. All other uses, including redistribution in whole or in */
|
|
/* part, are forbidden without prior written permission. */
|
|
/* */
|
|
/* This software is provided with absolutely no warranty and no */
|
|
/* support. */
|
|
/* */
|
|
/*************************************************************************/
|
|
|
|
#include "defs.h"
|
|
#include "memory.h"
|
|
#include "box.h"
|
|
#include "partition_grid.h"
|
|
#include "cost_zones.h"
|
|
|
|
#define NUM_DIRECTIONS 4
|
|
|
|
typedef enum { RIGHT, LEFT, UP, DOWN } direction;
|
|
|
|
static long Child_Sequence[NUM_DIRECTIONS][NUM_OFFSPRING] =
|
|
{
|
|
{ 0, 1, 2, 3 },
|
|
{ 2, 3, 0, 1 },
|
|
{ 0, 3, 2, 1 },
|
|
{ 2, 1, 0, 3 },
|
|
};
|
|
static long Direction_Sequence[NUM_DIRECTIONS][NUM_OFFSPRING] =
|
|
{
|
|
{ UP, RIGHT, RIGHT, DOWN },
|
|
{ DOWN, LEFT, LEFT, UP },
|
|
{ RIGHT, UP, UP, LEFT },
|
|
{ LEFT, DOWN, DOWN, RIGHT },
|
|
};
|
|
|
|
void ComputeSubTreeCosts(long my_id, box *b);
|
|
void CostZonesHelper(long my_id, box *b, long work, direction dir);
|
|
|
|
|
|
void
|
|
CostZones (long my_id)
|
|
{
|
|
PartitionIterate(my_id, ComputeSubTreeCosts, BOTTOM);
|
|
BARRIER(G_Memory->synch, Number_Of_Processors);
|
|
Local[my_id].Total_Work = Grid->subtree_cost;
|
|
Local[my_id].Min_Work = ((Local[my_id].Total_Work / Number_Of_Processors)
|
|
* my_id);
|
|
if (my_id == (Number_Of_Processors - 1))
|
|
Local[my_id].Max_Work = Local[my_id].Total_Work;
|
|
else
|
|
Local[my_id].Max_Work = (Local[my_id].Min_Work
|
|
+ (Local[my_id].Total_Work
|
|
/ Number_Of_Processors));
|
|
InitPartition(my_id);
|
|
CostZonesHelper(my_id, Grid, 0, RIGHT);
|
|
BARRIER(G_Memory->synch, Number_Of_Processors);
|
|
}
|
|
|
|
|
|
void
|
|
ComputeSubTreeCosts (long my_id, box *b)
|
|
{
|
|
box *pb;
|
|
|
|
if (b->type == PARENT) {
|
|
while (b->interaction_synch != b->num_children) {
|
|
}
|
|
}
|
|
b->interaction_synch = 0;
|
|
ComputeCostOfBox(b);
|
|
b->subtree_cost += b->cost;
|
|
pb = b->parent;
|
|
if (pb != NULL) {
|
|
ALOCK(G_Memory->lock_array, pb->exp_lock_index);
|
|
pb->subtree_cost += b->subtree_cost;
|
|
pb->interaction_synch += 1;
|
|
AULOCK(G_Memory->lock_array, pb->exp_lock_index);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
CostZonesHelper (long my_id, box *b, long work, direction dir)
|
|
{
|
|
box *cb;
|
|
long i;
|
|
long *next_child;
|
|
long *child_dir;
|
|
|
|
if (b->type == CHILDLESS) {
|
|
if (work >= Local[my_id].Min_Work)
|
|
InsertBoxInPartition(my_id, b);
|
|
}
|
|
else {
|
|
next_child = Child_Sequence[dir];
|
|
child_dir = Direction_Sequence[dir];
|
|
for (i = 0; (i < NUM_OFFSPRING) && (work < Local[my_id].Max_Work);
|
|
i++) {
|
|
cb = b->children[next_child[i]];
|
|
if (cb != NULL) {
|
|
if ((work + cb->subtree_cost) >= Local[my_id].Min_Work)
|
|
CostZonesHelper(my_id, cb, work, child_dir[i]);
|
|
work += cb->subtree_cost;
|
|
}
|
|
if (i == 2) {
|
|
if ((work >= Local[my_id].Min_Work)
|
|
&& (work < Local[my_id].Max_Work))
|
|
InsertBoxInPartition(my_id, b);
|
|
work += b->cost;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#undef DOWN
|
|
#undef UP
|
|
#undef LEFT
|
|
#undef RIGHT
|
|
#undef NUM_DIRECTIONS
|
|
|