— Jacek Pop?awski wrote:
I know how to start thread. But how can I set thread
priority? I must be sure,
that blocks calculating thread do not takes half of
CPU, it must be very slow.
I thought about loop:
- calc part of data
- SDL_Delay(100)
But is there a better solution?
The best general solution is exactly that, but I think
a better solution is to take into account how long the
calculations HAVE taken and when they NEED to be done
(with a small comfort-zone to accomidate scheduling
inconsistancies)… You might even want to spin a
seperate thread for each block, and have each thread
pace itself against when it needs to be done. This
may make the program run better on multi-CPU machines.
Maybe something like:
typedef struct {
float estimated_time_until_needed;
/* <0 means needed now /
uint chunks_calculated;
MapBlockData pData;
} BlockCacheData;
enum { CHUNKS_PER_BLOCK = 256 };
enum { CACHE_SIZE = 128 };
BlockCacheData block_cache[CACHE_SIZE];
int StartCalculateThread(void* pVoidQuitThread)
{
bool* pQuitThread = (bool*)pVoidQuitThread;
uint i;
for(i=0; i < CACHE_SIZE; i++)
{
block_cache[i].pData = NULL;
block_cache[i].chunks_calculated =
CHUNKS_PER_BLOCK;
}
while(!(pQuitThread))
{
update_estimated_time_until_needed();
BlockCacheData pSortedBlocks[CACHE_SIZE];
uint SortedBlocksNeedingUpdate;
sort_blocks_needing_update(pSortedBlocks,
&SortedBlocksNeedingUpdate);
#if ASSERTS_ENABLED
assert(SortedBlocksNeedingUpdate <=
CACHE_SIZE);
for(
i=0;
i < SortedBlocksNeedingUpdate;
i++
)
{
assert(pSortedBlocks[i]->chunks_calculated
< CHUNKS_PER_BLOCK);
assert((i==0) ||
(pSortedBlocks[i-1]->estimated_time_until_needed <=
pSortedBlocks[i]->estimated_time_until_needed);
}
#endif /* ASSERTS_ENABLED */
uint TotalChunksNeeded=0;
uint MinimumMsecPerChunk = 500;
/* Maximum sleep time 500 msec */
for(
i=0;
(i < SortedBlocksNeedingUpdate) &&
(MinimumMsecPerChunk > 0);
i++
)
{
TotalChunksNeeded += CHUNKS_PER_BLOCK -
(pSortedBlocks[i]->chunks_calculated);
assert(TotalChunksNeeded);
uint Rate =
(pSortedBlocks[i]->estimated_time_until_needed * 1000
/ pTotalChunksNeeded);
if( Rate < MinimumMsecPerChunk)
{
MinimumMsecPerChunk = Rate;
}
}
uint MsecToSleepAfterCalcs =
MinimumMsecPerChunk;
if( TotalChunksNeeded )
{
uint CalculationsMade = 0;
ulong StartTime = SDL_GetTicks();
do {
calculate_chunk();
CalculationsMade++;
TotalChunksNeeded–;
} while ((TotalChunksNeeded > 0) &&
(CalculationsMade < CHUNKS_PER_BLOCK) &&
((SDL_GetTicks() - StartTime) > (CalculationsMade *
MinimumMsecPerChunk))) ;
if ((SDL_GetTicks() - StartTime) >
(CalculationsMade * MinimumMsecPerChunk))
{
MsecToSleepAfterCalcs = 0 ;
}
else
{
MsecToSleepAfterCalcs =
((CalculationsMade * MinimumMsecPerChunk) -
(SDL_GetTicks() - StartTime)) ;
}
}
SDL_Delay(MsecToSleepAfterCalcs)
}
}
This is alot more complex than
- calc part of data
- SDL_Delay(100)
but it should auto-throttle with load…
(Hmmm… now that I’ve written all that code, I wonder
if the original solution would have been better…)
Hope that helps,
-Loren__________________________________________________
Do You Yahoo!?
Yahoo! Health - Feel better, live better