Viewing Issue Advanced Details
ID Category [?] Severity [?] Reproducibility Date Submitted Last Update
08692 Core Minor Always Jul 1, 2023, 17:04 3 days ago
Tester holub View Status Public Platform
Assigned To Resolution Open OS
Status [?] Driver
Version 0.256 Fixed in Version Build
Fixed in Git Commit Github Pull Request #
Summary 08692: tap performance
Description installed taps add significant performance degradation.
Even empty tap added to reads in whole OPCODES space slows everything down notably (in my case aprox. 20%).

empty tap:
address_space &op = m_maincpu->space(AS_OPCODES);
op.install_read_tap(0x0000, 0xffff, "accel_control", [](offs_t offset, u8 &data, u8 mem_mask)
{});
Steps To Reproduce
Additional Information
Github Commit
Flags
Regression Version
Affected Sets / Systems
Attached Files
 
Relationships
There are no relationship linked to this issue.
Notes
3
User avatar
No.21605
holub
Tester
Jul 1, 2023, 19:59
chat log related to the topic:

og>
template<int Width, int AddrShift> typename emu::detail::handler_entry_size<Width>::uX handler_entry_read_tap<Width, AddrShift>::read(offs_t offset, uX mem_mask) const
{
        this->ref();

        uX data = this->m_next->read(offset, mem_mask);
        m_tap(offset, data, mem_mask);

        this->unref();
        return data;
}

for reference
ref/unref is incrementing/decrementing a counter and testing for zero. Sadly it's required because the access may delete the tap
and if the tap is deleted you get a use-after-free on the m_tap(...) call (that's the delegate call)

smf> could the tap delete be defered?

og> yes, it is, by incrementing its reference counter at the start of the method and decrementing it afterwards
unref deletes the object if the refcount reaches 0

smf> I mean without refcounting in the method, like when it gets removed then put it in a list of things to delete at the next vblank
that way you only have a cost when deleting, not on every method call

og> could be something to look at, yes
User avatar
No.23167
holub
Tester
3 days ago
I did couple quick experiments. Looks like moving free from unref doesn't change situation. Even if 100% times it's false, that doesn't make too much difference. Only removing if completely make runtime a bit faster.
User avatar
No.23168
galibert
Developer
3 days ago
Yup, it's not about the free, which almost never happens, it's all about reading the refcount and testing it. Reads are costly, conditional branches are costly. Writes, comparatively, aren't.