Re-inlined core attotime functions. This makes a significant difference

when running with high interleaves (~2x speed running Dig Dug at perfect
interleave).
This commit is contained in:
Aaron Giles 2008-11-04 05:45:54 +00:00
parent 807a9b1014
commit 7d291c792f
3 changed files with 241 additions and 275 deletions

View File

@ -23,181 +23,10 @@ const attotime attotime_never = STATIC_ATTOTIME_IN_SEC(ATTOTIME_MAX_SECONDS);
/***************************************************************************
CONVERSION HELPERS
***************************************************************************/
/*-------------------------------------------------
attotime_to_attoseconds - convert a attotime
to attoseconds, clamping to maximum positive/
negative values
-------------------------------------------------*/
attoseconds_t attotime_to_attoseconds(attotime _time)
{
/* positive values between 0 and 1 second */
if (_time.seconds == 0)
return _time.attoseconds;
/* negative values between -1 and 0 seconds */
else if (_time.seconds == -1)
return _time.attoseconds - ATTOSECONDS_PER_SECOND;
/* out-of-range positive values */
else if (_time.seconds > 0)
return ATTOSECONDS_PER_SECOND;
/* out-of-range negative values */
else
return -ATTOSECONDS_PER_SECOND;
}
/*-------------------------------------------------
attotime_to_ticks - convert an attotime to
clock ticks at the given frequency
-------------------------------------------------*/
INT64 attotime_to_ticks(attotime _time, INT32 frequency)
{
INT32 fracticks = attotime_mul(attotime_make(0, _time.attoseconds), frequency).seconds;
return (INT64)_time.seconds * (INT64)frequency + fracticks;
}
/*-------------------------------------------------
ticks_to_attotime - convert clock ticks at
the given frequency to an attotime
-------------------------------------------------*/
attotime ticks_to_attotime(INT64 ticks, INT32 frequency)
{
attotime result;
result.seconds = ticks / frequency;
result.attoseconds = HZ_TO_ATTOSECONDS(frequency) * (ticks - (INT64)result.seconds * (INT64)frequency);
return result;
}
/***************************************************************************
CORE MATH FUNCTIONS
***************************************************************************/
/*-------------------------------------------------
attotime_add - add two attotimes
-------------------------------------------------*/
attotime attotime_add(attotime _time1, attotime _time2)
{
attotime result;
/* if one of the items is attotime_never, return attotime_never */
if (_time1.seconds >= ATTOTIME_MAX_SECONDS || _time2.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
/* add the seconds and attoseconds */
result.attoseconds = _time1.attoseconds + _time2.attoseconds;
result.seconds = _time1.seconds + _time2.seconds;
/* normalize and return */
if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
{
result.attoseconds -= ATTOSECONDS_PER_SECOND;
result.seconds++;
}
/* overflow */
if (result.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
return result;
}
/*-------------------------------------------------
attotime_add_attoseconds - add attoseconds
to a attotime
-------------------------------------------------*/
attotime attotime_add_attoseconds(attotime _time1, attoseconds_t _attoseconds)
{
attotime result;
/* if one of the items is attotime_never, return attotime_never */
if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
/* add the seconds and attoseconds */
result.attoseconds = _time1.attoseconds + _attoseconds;
result.seconds = _time1.seconds;
/* normalize and return */
if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
{
result.attoseconds -= ATTOSECONDS_PER_SECOND;
result.seconds++;
}
/* overflow */
if (result.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
return result;
}
/*-------------------------------------------------
attotime_sub - subtract two attotimes
-------------------------------------------------*/
attotime attotime_sub(attotime _time1, attotime _time2)
{
attotime result;
/* if time1 is attotime_never, return attotime_never */
if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
/* add the seconds and attoseconds */
result.attoseconds = _time1.attoseconds - _time2.attoseconds;
result.seconds = _time1.seconds - _time2.seconds;
/* normalize and return */
if (result.attoseconds < 0)
{
result.attoseconds += ATTOSECONDS_PER_SECOND;
result.seconds--;
}
return result;
}
/*-------------------------------------------------
attotime_sub_attoseconds - subtract
attoseconds from a attotime
-------------------------------------------------*/
attotime attotime_sub_attoseconds(attotime _time1, attoseconds_t _attoseconds)
{
attotime result;
/* if time1 is attotime_never, return attotime_never */
if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
/* add the seconds and attoseconds */
result.attoseconds = _time1.attoseconds - _attoseconds;
result.seconds = _time1.seconds;
/* normalize and return */
if (result.attoseconds < 0)
{
result.attoseconds += ATTOSECONDS_PER_SECOND;
result.seconds--;
}
return result;
}
/*-------------------------------------------------
attotime_mul - multiply an attotime by
a constant
@ -282,65 +111,13 @@ attotime attotime_div(attotime _time1, UINT32 factor)
}
/*-------------------------------------------------
attotime_compare - compare two attotimes
-------------------------------------------------*/
int attotime_compare(attotime _time1, attotime _time2)
{
if (_time1.seconds > _time2.seconds)
return 1;
if (_time1.seconds < _time2.seconds)
return -1;
if (_time1.attoseconds > _time2.attoseconds)
return 1;
if (_time1.attoseconds < _time2.attoseconds)
return -1;
return 0;
}
/*-------------------------------------------------
attotime_min - return the minimum of two
attotimes
-------------------------------------------------*/
attotime attotime_min(attotime _time1, attotime _time2)
{
if (_time1.seconds > _time2.seconds)
return _time2;
if (_time1.seconds < _time2.seconds)
return _time1;
if (_time1.attoseconds > _time2.attoseconds)
return _time2;
return _time1;
}
/*-------------------------------------------------
attotime_max - return the maximum of two
attotimes
-------------------------------------------------*/
attotime attotime_max(attotime _time1, attotime _time2)
{
if (_time1.seconds > _time2.seconds)
return _time1;
if (_time1.seconds < _time2.seconds)
return _time2;
if (_time1.attoseconds > _time2.attoseconds)
return _time1;
return _time2;
}
/***************************************************************************
MISC UTILITIES
***************************************************************************/
/*-------------------------------------------------
attotime_compare - return a temporary
attotime_string - return a temporary
printable string describing an attotime
-------------------------------------------------*/

View File

@ -132,47 +132,14 @@ extern const attotime attotime_never;
FUNCTION PROTOTYPES
***************************************************************************/
/* ----- conversion helpers ----- */
/* convert an attotime to attoseconds, clamping to maximum positive/negative values */
attoseconds_t attotime_to_attoseconds(attotime _time);
/* convert an attotime to clock ticks at the given frequency */
INT64 attotime_to_ticks(attotime _time, INT32 frequency);
/* convert clock ticks at the given frequency to an attotime */
attotime ticks_to_attotime(INT64 ticks, INT32 frequency);
/* ----- core math functions ----- */
/* add two attotimes */
attotime attotime_add(attotime _time1, attotime _time2);
/* add attoseconds to an attotime */
attotime attotime_add_attoseconds(attotime _time1, attoseconds_t _attoseconds);
/* subtract two attotimes */
attotime attotime_sub(attotime _time1, attotime _time2);
/* subtract attoseconds from an attotime */
attotime attotime_sub_attoseconds(attotime _time1, attoseconds_t _attoseconds);
/* multiply an attotime by a constant */
attotime attotime_mul(attotime _time1, UINT32 factor);
/* divide an attotime by a constant */
attotime attotime_div(attotime _time1, UINT32 factor);
/* compare two attotimes */
int attotime_compare(attotime _time1, attotime _time2);
/* return the minimum of two attotimes */
attotime attotime_min(attotime _time1, attotime _time2);
/* return the maximum of two attotimes */
attotime attotime_max(attotime _time1, attotime _time2);
/* ----- misc utilities ----- */
@ -229,4 +196,222 @@ INLINE attotime double_to_attotime(double _time)
}
/*-------------------------------------------------
attotime_to_attoseconds - convert a attotime
to attoseconds, clamping to maximum positive/
negative values
-------------------------------------------------*/
INLINE attoseconds_t attotime_to_attoseconds(attotime _time)
{
/* positive values between 0 and 1 second */
if (_time.seconds == 0)
return _time.attoseconds;
/* negative values between -1 and 0 seconds */
else if (_time.seconds == -1)
return _time.attoseconds - ATTOSECONDS_PER_SECOND;
/* out-of-range positive values */
else if (_time.seconds > 0)
return ATTOSECONDS_PER_SECOND;
/* out-of-range negative values */
else
return -ATTOSECONDS_PER_SECOND;
}
/*-------------------------------------------------
attotime_to_ticks - convert an attotime to
clock ticks at the given frequency
-------------------------------------------------*/
INLINE INT64 attotime_to_ticks(attotime _time, INT32 frequency)
{
INT32 fracticks = attotime_mul(attotime_make(0, _time.attoseconds), frequency).seconds;
return (INT64)_time.seconds * (INT64)frequency + fracticks;
}
/*-------------------------------------------------
ticks_to_attotime - convert clock ticks at
the given frequency to an attotime
-------------------------------------------------*/
INLINE attotime ticks_to_attotime(INT64 ticks, INT32 frequency)
{
attotime result;
result.seconds = ticks / frequency;
result.attoseconds = HZ_TO_ATTOSECONDS(frequency) * (ticks - (INT64)result.seconds * (INT64)frequency);
return result;
}
/*-------------------------------------------------
attotime_add - add two attotimes
-------------------------------------------------*/
INLINE attotime attotime_add(attotime _time1, attotime _time2)
{
attotime result;
/* if one of the items is attotime_never, return attotime_never */
if (_time1.seconds >= ATTOTIME_MAX_SECONDS || _time2.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
/* add the seconds and attoseconds */
result.attoseconds = _time1.attoseconds + _time2.attoseconds;
result.seconds = _time1.seconds + _time2.seconds;
/* normalize and return */
if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
{
result.attoseconds -= ATTOSECONDS_PER_SECOND;
result.seconds++;
}
/* overflow */
if (result.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
return result;
}
/*-------------------------------------------------
attotime_add_attoseconds - add attoseconds
to a attotime
-------------------------------------------------*/
INLINE attotime attotime_add_attoseconds(attotime _time1, attoseconds_t _attoseconds)
{
attotime result;
/* if one of the items is attotime_never, return attotime_never */
if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
/* add the seconds and attoseconds */
result.attoseconds = _time1.attoseconds + _attoseconds;
result.seconds = _time1.seconds;
/* normalize and return */
if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
{
result.attoseconds -= ATTOSECONDS_PER_SECOND;
result.seconds++;
}
/* overflow */
if (result.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
return result;
}
/*-------------------------------------------------
attotime_sub - subtract two attotimes
-------------------------------------------------*/
INLINE attotime attotime_sub(attotime _time1, attotime _time2)
{
attotime result;
/* if time1 is attotime_never, return attotime_never */
if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
/* add the seconds and attoseconds */
result.attoseconds = _time1.attoseconds - _time2.attoseconds;
result.seconds = _time1.seconds - _time2.seconds;
/* normalize and return */
if (result.attoseconds < 0)
{
result.attoseconds += ATTOSECONDS_PER_SECOND;
result.seconds--;
}
return result;
}
/*-------------------------------------------------
attotime_sub_attoseconds - subtract
attoseconds from a attotime
-------------------------------------------------*/
INLINE attotime attotime_sub_attoseconds(attotime _time1, attoseconds_t _attoseconds)
{
attotime result;
/* if time1 is attotime_never, return attotime_never */
if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
return attotime_never;
/* add the seconds and attoseconds */
result.attoseconds = _time1.attoseconds - _attoseconds;
result.seconds = _time1.seconds;
/* normalize and return */
if (result.attoseconds < 0)
{
result.attoseconds += ATTOSECONDS_PER_SECOND;
result.seconds--;
}
return result;
}
/*-------------------------------------------------
attotime_compare - compare two attotimes
-------------------------------------------------*/
INLINE int attotime_compare(attotime _time1, attotime _time2)
{
if (_time1.seconds > _time2.seconds)
return 1;
if (_time1.seconds < _time2.seconds)
return -1;
if (_time1.attoseconds > _time2.attoseconds)
return 1;
if (_time1.attoseconds < _time2.attoseconds)
return -1;
return 0;
}
/*-------------------------------------------------
attotime_min - return the minimum of two
attotimes
-------------------------------------------------*/
INLINE attotime attotime_min(attotime _time1, attotime _time2)
{
if (_time1.seconds > _time2.seconds)
return _time2;
if (_time1.seconds < _time2.seconds)
return _time1;
if (_time1.attoseconds > _time2.attoseconds)
return _time2;
return _time1;
}
/*-------------------------------------------------
attotime_max - return the maximum of two
attotimes
-------------------------------------------------*/
INLINE attotime attotime_max(attotime _time1, attotime _time2)
{
if (_time1.seconds > _time2.seconds)
return _time1;
if (_time1.seconds < _time2.seconds)
return _time2;
if (_time1.attoseconds > _time2.attoseconds)
return _time1;
return _time2;
}
#endif /* __ATTOTIME_H__ */

View File

@ -11,6 +11,7 @@
#include "driver.h"
#include "profiler.h"
#include "eminline.h"
#include "debugger.h"
@ -115,6 +116,7 @@ static attotime perfect_interleave;
static void cpuexec_exit(running_machine *machine);
static void cpuexec_reset(running_machine *machine);
static void cpu_inittimers(running_machine *machine);
static void update_clock_information(running_machine *machine, int cpunum);
static TIMER_CALLBACK( end_interleave_boost );
static TIMER_CALLBACK( trigger_partial_frame_interrupt );
static void compute_perfect_interleave(running_machine *machine);
@ -135,6 +137,7 @@ void cpuexec_init(running_machine *machine)
int cpunum;
/* loop over all our CPUs */
memset(cpu, 0, sizeof(cpu));
for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
{
cpu_type cputype = machine->config->cpu[cpunum].type;
@ -145,15 +148,13 @@ void cpuexec_init(running_machine *machine)
break;
/* initialize the cpuinfo struct */
memset(&cpu[cpunum], 0, sizeof(cpu[cpunum]));
cpu[cpunum].suspend = SUSPEND_REASON_RESET;
cpu[cpunum].clock = (UINT64)machine->config->cpu[cpunum].clock * cputype_clock_multiplier(cputype) / cputype_clock_divider(cputype);
cpu[cpunum].clockscale = 1.0;
cpu[cpunum].localtime = attotime_zero;
/* compute the cycle times */
cycles_per_second[cpunum] = cpu[cpunum].clockscale * cpu[cpunum].clock;
attoseconds_per_cycle[cpunum] = ATTOSECONDS_PER_SECOND / (cpu[cpunum].clockscale * cpu[cpunum].clock);
update_clock_information(machine, cpunum);
/* register some of our variables for later */
state_save_register_item("cpu", cpunum, cpu[cpunum].suspend);
@ -189,8 +190,9 @@ void cpuexec_init(running_machine *machine)
add_reset_callback(machine, cpuexec_reset);
add_exit_callback(machine, cpuexec_exit);
/* compute the perfect interleave factor */
compute_perfect_interleave(machine);
/* allocate timers to handle interleave boosts */
interleave_boost_timer = timer_alloc(NULL, NULL);
interleave_boost_timer_end = timer_alloc(end_interleave_boost, NULL);
}
@ -267,6 +269,10 @@ void cpuexec_timeslice(running_machine *machine)
/* only process if we're not suspended */
if (!cpu[cpunum].suspend)
{
attotime delta = attotime_sub(target, cpu[cpunum].localtime);
if (delta.seconds >= 0)
{
/* compute how long to run */
cycles_running = ATTOTIME_TO_CYCLES(cpunum, attotime_sub(target, cpu[cpunum].localtime));
LOG((" cpu %d: %d cycles\n", cpunum, cycles_running));
@ -306,6 +312,7 @@ void cpuexec_timeslice(running_machine *machine)
LOG((" (new target)\n"));
}
}
}
}
}
@ -447,7 +454,7 @@ static void update_clock_information(running_machine *machine, int cpunum)
/* recompute cps and spc */
cycles_per_second[cpunum] = (double)cpu[cpunum].clock * cpu[cpunum].clockscale;
attoseconds_per_cycle[cpunum] = ATTOSECONDS_PER_SECOND / ((double)cpu[cpunum].clock * cpu[cpunum].clockscale);
/* re-compute the perfect interleave factor */
compute_perfect_interleave(machine);
}
@ -902,16 +909,17 @@ static void compute_perfect_interleave(running_machine *machine)
perfect_interleave = attotime_zero;
perfect_interleave.attoseconds = ATTOSECONDS_PER_SECOND - 1;
for (cpunum = 1; machine->config->cpu[cpunum].type != CPU_DUMMY; cpunum++)
{
/* find the 2nd smallest cycle interval */
if (attoseconds_per_cycle[cpunum] < smallest)
if (attoseconds_per_cycle[cpunum] != 0)
{
perfect_interleave.attoseconds = smallest;
smallest = attoseconds_per_cycle[cpunum];
/* find the 2nd smallest cycle interval */
if (attoseconds_per_cycle[cpunum] < smallest)
{
perfect_interleave.attoseconds = smallest;
smallest = attoseconds_per_cycle[cpunum];
}
else if (attoseconds_per_cycle[cpunum] < perfect_interleave.attoseconds)
perfect_interleave.attoseconds = attoseconds_per_cycle[cpunum];
}
else if (attoseconds_per_cycle[cpunum] < perfect_interleave.attoseconds)
perfect_interleave.attoseconds = attoseconds_per_cycle[cpunum];
}
/* adjust the final value */
if (perfect_interleave.attoseconds == ATTOSECONDS_PER_SECOND - 1)
@ -940,10 +948,6 @@ static void cpu_inittimers(running_machine *machine)
timeslice_timer = timer_alloc(cpu_timeslicecallback, NULL);
timer_adjust_periodic(timeslice_timer, timeslice_period, 0, timeslice_period);
/* allocate timers to handle interleave boosts */
interleave_boost_timer = timer_alloc(NULL, NULL);
interleave_boost_timer_end = timer_alloc(end_interleave_boost, NULL);
/* register the interrupt handler callbacks */
for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
{