DelayQueue tuning:

* Remove stringstream from DelayQueueMember::name
    * Use a bit mask instead of modulo in DelayQueue
This commit is contained in:
Christian Speckner 2017-05-16 01:24:03 +02:00
parent 4c555a83ed
commit b2c8c3ff81
5 changed files with 126 additions and 36 deletions

86
src/common/smartmod.hxx Normal file
View File

@ -0,0 +1,86 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef SMARTMOD_HXX
#define SMARTMOD_HXX
#include "bspf.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<unsigned base>
uInt8 smartmod(uInt8 x)
{
return x % base;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<>
inline uInt8 smartmod<2>(uInt8 x)
{
return x & 0x01;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<>
inline uInt8 smartmod<4>(uInt8 x)
{
return x & 0x03;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<>
inline uInt8 smartmod<8>(uInt8 x)
{
return x & 0x07;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<>
inline uInt8 smartmod<16>(uInt8 x)
{
return x & 0x0F;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<>
inline uInt8 smartmod<32>(uInt8 x)
{
return x & 0x1F;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<>
inline uInt8 smartmod<64>(uInt8 x)
{
return x & 0x3F;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<>
inline uInt8 smartmod<128>(uInt8 x)
{
return x & 0x7F;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<>
inline uInt8 smartmod<256>(uInt8 x)
{
return x & 0xFF;
}
#endif // SMARTMOD_HXX

View File

@ -20,12 +20,13 @@
#include "Serializable.hxx" #include "Serializable.hxx"
#include "bspf.hxx" #include "bspf.hxx"
#include "smartmod.hxx"
#include "DelayQueueMember.hxx" #include "DelayQueueMember.hxx"
template<int length, int capacity> template<unsigned length, unsigned capacity>
class DelayQueueIteratorImpl; class DelayQueueIteratorImpl;
template<int length, int capacity> template<unsigned length, unsigned capacity>
class DelayQueue : public Serializable class DelayQueue : public Serializable
{ {
public: public:
@ -47,7 +48,7 @@ class DelayQueue : public Serializable
*/ */
bool save(Serializer& out) const override; bool save(Serializer& out) const override;
bool load(Serializer& in) override; bool load(Serializer& in) override;
string name() const override { return "TIA_DelayQueue"; } string name() const override;
private: private:
DelayQueueMember<capacity> myMembers[length]; DelayQueueMember<capacity> myMembers[length];
@ -66,7 +67,7 @@ class DelayQueue : public Serializable
// ############################################################################ // ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
DelayQueue<length, capacity>::DelayQueue() DelayQueue<length, capacity>::DelayQueue()
: myIndex(0) : myIndex(0)
{ {
@ -74,7 +75,7 @@ DelayQueue<length, capacity>::DelayQueue()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
void DelayQueue<length, capacity>::push(uInt8 address, uInt8 value, uInt8 delay) void DelayQueue<length, capacity>::push(uInt8 address, uInt8 value, uInt8 delay)
{ {
if (delay >= length) if (delay >= length)
@ -85,14 +86,14 @@ void DelayQueue<length, capacity>::push(uInt8 address, uInt8 value, uInt8 delay)
if (currentIndex < 0xFF) if (currentIndex < 0xFF)
myMembers[currentIndex].remove(address); myMembers[currentIndex].remove(address);
uInt8 index = (myIndex + delay) % length; uInt8 index = smartmod<length>(myIndex + delay);
myMembers[index].push(address, value); myMembers[index].push(address, value);
myIndices[address] = index; myIndices[address] = index;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
void DelayQueue<length, capacity>::reset() void DelayQueue<length, capacity>::reset()
{ {
for (uInt8 i = 0; i < length; i++) for (uInt8 i = 0; i < length; i++)
@ -103,7 +104,7 @@ void DelayQueue<length, capacity>::reset()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
template<class T> template<class T>
void DelayQueue<length, capacity>::execute(T executor) void DelayQueue<length, capacity>::execute(T executor)
{ {
@ -116,11 +117,11 @@ void DelayQueue<length, capacity>::execute(T executor)
currentMember.clear(); currentMember.clear();
myIndex = (myIndex + 1) % length; myIndex = smartmod<length>(myIndex + 1);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
bool DelayQueue<length, capacity>::save(Serializer& out) const bool DelayQueue<length, capacity>::save(Serializer& out) const
{ {
try try
@ -143,7 +144,7 @@ bool DelayQueue<length, capacity>::save(Serializer& out) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
bool DelayQueue<length, capacity>::load(Serializer& in) bool DelayQueue<length, capacity>::load(Serializer& in)
{ {
try try
@ -165,4 +166,11 @@ bool DelayQueue<length, capacity>::load(Serializer& in)
return true; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<unsigned length, unsigned capacity>
string DelayQueue<length, capacity>::name() const
{
return "TIA_DelayQueue";
}
#endif // TIA_DELAY_QUEUE #endif // TIA_DELAY_QUEUE

View File

@ -23,7 +23,7 @@
#include "DelayQueueMember.hxx" #include "DelayQueueMember.hxx"
#include "DelayQueueIterator.hxx" #include "DelayQueueIterator.hxx"
template<int length, int capacity> template<unsigned length, unsigned capacity>
class DelayQueueIteratorImpl : public DelayQueueIterator class DelayQueueIteratorImpl : public DelayQueueIterator
{ {
public: public:
@ -55,8 +55,8 @@ class DelayQueueIteratorImpl : public DelayQueueIterator
// ############################################################################ // ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
DelayQueueIteratorImpl<length,capacity>::DelayQueueIteratorImpl( DelayQueueIteratorImpl<length, capacity>::DelayQueueIteratorImpl(
const DelayQueue<length, capacity>& delayQueue const DelayQueue<length, capacity>& delayQueue
) )
: myDelayQueue(delayQueue), : myDelayQueue(delayQueue),
@ -68,14 +68,14 @@ DelayQueueIteratorImpl<length,capacity>::DelayQueueIteratorImpl(
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
bool DelayQueueIteratorImpl<length, capacity>::isValid() const bool DelayQueueIteratorImpl<length, capacity>::isValid() const
{ {
return myDelayCycle < length; return myDelayCycle < length;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
uInt8 DelayQueueIteratorImpl<length, capacity>::delay() const uInt8 DelayQueueIteratorImpl<length, capacity>::delay() const
{ {
if (!isValid()) { if (!isValid()) {
@ -86,7 +86,7 @@ uInt8 DelayQueueIteratorImpl<length, capacity>::delay() const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
uInt8 DelayQueueIteratorImpl<length, capacity>::address() const uInt8 DelayQueueIteratorImpl<length, capacity>::address() const
{ {
if (!isValid()) { if (!isValid()) {
@ -97,7 +97,7 @@ uInt8 DelayQueueIteratorImpl<length, capacity>::address() const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
uInt8 DelayQueueIteratorImpl<length, capacity>::value() const uInt8 DelayQueueIteratorImpl<length, capacity>::value() const
{ {
if (!isValid()) { if (!isValid()) {
@ -108,7 +108,7 @@ uInt8 DelayQueueIteratorImpl<length, capacity>::value() const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
bool DelayQueueIteratorImpl<length, capacity>::next() bool DelayQueueIteratorImpl<length, capacity>::next()
{ {
if (!isValid()) return false; if (!isValid()) return false;
@ -126,7 +126,7 @@ bool DelayQueueIteratorImpl<length, capacity>::next()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int length, int capacity> template<unsigned length, unsigned capacity>
uInt8 DelayQueueIteratorImpl<length, capacity>::currentIndex() const uInt8 DelayQueueIteratorImpl<length, capacity>::currentIndex() const
{ {
return (myDelayQueue.myIndex + myDelayCycle) % length; return (myDelayQueue.myIndex + myDelayCycle) % length;

View File

@ -21,7 +21,7 @@
#include "Serializable.hxx" #include "Serializable.hxx"
#include "bspf.hxx" #include "bspf.hxx"
template<int capacity> template<unsigned capacity>
class DelayQueueMember : public Serializable { class DelayQueueMember : public Serializable {
public: public:
@ -65,13 +65,13 @@ class DelayQueueMember : public Serializable {
// ############################################################################ // ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity> template<unsigned capacity>
DelayQueueMember<capacity>::DelayQueueMember() DelayQueueMember<capacity>::DelayQueueMember()
: mySize(0) : mySize(0)
{} {}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity> template<unsigned capacity>
void DelayQueueMember<capacity>::push(uInt8 address, uInt8 value) void DelayQueueMember<capacity>::push(uInt8 address, uInt8 value)
{ {
if (mySize == capacity) throw runtime_error("delay queue overflow"); if (mySize == capacity) throw runtime_error("delay queue overflow");
@ -81,7 +81,7 @@ void DelayQueueMember<capacity>::push(uInt8 address, uInt8 value)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity> template<unsigned capacity>
void DelayQueueMember<capacity>::remove(uInt8 address) void DelayQueueMember<capacity>::remove(uInt8 address)
{ {
uInt8 index; uInt8 index;
@ -100,14 +100,14 @@ void DelayQueueMember<capacity>::remove(uInt8 address)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity> template<unsigned capacity>
void DelayQueueMember<capacity>::clear() void DelayQueueMember<capacity>::clear()
{ {
mySize = 0; mySize = 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity> template<unsigned capacity>
bool DelayQueueMember<capacity>::save(Serializer& out) const bool DelayQueueMember<capacity>::save(Serializer& out) const
{ {
try try
@ -130,7 +130,7 @@ bool DelayQueueMember<capacity>::save(Serializer& out) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity> template<unsigned capacity>
bool DelayQueueMember<capacity>::load(Serializer& in) bool DelayQueueMember<capacity>::load(Serializer& in)
{ {
try try
@ -154,14 +154,10 @@ bool DelayQueueMember<capacity>::load(Serializer& in)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<int capacity> template<unsigned capacity>
string DelayQueueMember<capacity>::name() const string DelayQueueMember<capacity>::name() const
{ {
stringstream ss; return "TIA_DelayQueueMember";
ss << "TIA_DelayQueueMember<" << capacity << ">";
return ss.str();
} }
#endif // TIA_DELAY_QUEUE_MEMBER #endif // TIA_DELAY_QUEUE_MEMBER

View File

@ -449,8 +449,8 @@ class TIA : public Device
Sound& mySound; Sound& mySound;
Settings& mySettings; Settings& mySettings;
static constexpr int delayQueueLength = 10; static constexpr unsigned delayQueueLength = 16;
static constexpr int delayQueueSize = 20; static constexpr unsigned delayQueueSize = 16;
DelayQueue<delayQueueLength, delayQueueSize> myDelayQueue; DelayQueue<delayQueueLength, delayQueueSize> myDelayQueue;
FrameManager myFrameManager; FrameManager myFrameManager;