qiufuyu123 / CasioEmuNeo

卡西欧classwizard系列模拟器,支持调试,rop一件注入
GNU General Public License v3.0
38 stars 8 forks source link

性能问题 #19

Closed bczhc closed 5 months ago

bczhc commented 5 months ago

用这个模拟器一直觉得卡卡的,按键时会出现丢键的情况,比较影响体验。能确认按键按在判定区域上。测试commit: 90db1e80149dc00942252e3db6cd04a485c38a07

我在Discussion https://github.com/Physics365/991CN-X-CW-Decompilation/discussions/37 里可视化内存的做法就是每0.1s dump出整个内存,即使这样也依然流畅。我觉得应该是调试窗口的原因。这儿是否优化吗?比如把emulator和DebugUi的更新分开,不要放到一个UI looper里。

bczhc commented 5 months ago

貌似鼠标按键比用键盘按键,更严重些

qiufuyu123 commented 5 months ago

这个确实,我给他写个多线程应该没啥问题。 刚刚验证了一下,去掉imgui就不卡了 🥲

qiufuyu123 commented 5 months ago

https://github.com/qiufuyu123/CasioEmuNeo/assets/60765480/bcc1b463-8425-4513-bd25-4d8aa725fbfe

看一下新的commit,我把渲染速率锁定120帧,会好一点 image casioemu.cpp

bczhc commented 5 months ago

感觉好起来了!就是启动时有几率崩溃,release更容易触发。

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000558e84f9e2c4 in elem_cmp (a=..., b=...) at emulator/Gui/CodeViewer.cpp:69
69      return get_real_pc(a.segment, a.offset)<get_real_pc(b.segment, b.offset);
[Current thread is 1 (Thread 0x7f18856006c0 (LWP 1227748))]
(gdb) bt
#0  0x0000558e84f9e2c4 in elem_cmp (a=..., b=...) at emulator/Gui/CodeViewer.cpp:69
#1  0x0000558e84fa09a1 in __gnu_cxx::__ops::_Iter_comp_val<bool (*)(CodeElem const&, CodeElem const&)>::operator()<__gnu_cxx::__normal_iterator<CodeElem*, std::vector<CodeElem, std::allocator<CodeElem> > >, CodeElem const> (this=0x7f18855ffaa0, __it=<error reading variable: Cannot access memory at address 0x12>, __val=...) at /usr/include/c++/13.2.1/bits/predefined_ops.h:196
#2  0x0000558e84fa034b in std::__lower_bound<__gnu_cxx::__normal_iterator<CodeElem*, std::vector<CodeElem, std::allocator<CodeElem> > >, CodeElem, __gnu_cxx::__ops::_Iter_comp_val<bool (*)(CodeElem const&, CodeElem const&)> > (__first=<error reading variable: Cannot access memory at address 0x6>, __last=<error reading variable: Cannot access memory at address 0x21>, __val=..., __comp=...)
    at /usr/include/c++/13.2.1/bits/stl_algobase.h:1472
#3  0x0000558e84f9fc91 in std::lower_bound<__gnu_cxx::__normal_iterator<CodeElem*, std::vector<CodeElem, std::allocator<CodeElem> > >, CodeElem, bool (*)(CodeElem const&, CodeElem const&)> (
    __first=<error reading variable: Cannot access memory at address 0x6>, __last=<error reading variable: Cannot access memory at address 0x21>, __val=...,
    __comp=0x558e84f9e2af <elem_cmp(CodeElem const&, CodeElem const&)>) at /usr/include/c++/13.2.1/bits/stl_algo.h:2015
#4  0x0000558e84f9e3c3 in CodeViewer::LookUp (this=0x558e878e3240, seg=0 '\000', offset=37292, idx=0x7f18855ffc18) at emulator/Gui/CodeViewer.cpp:82
#5  0x0000558e84f9e5f4 in CodeViewer::TryTrigBP (this=0x558e878e3240, seg=0 '\000', offset=37292, bp_mode=false) at emulator/Gui/CodeViewer.cpp:107
#6  0x0000558e84f88240 in casioemu::CPU::Next (this=0x558e86f47330) at emulator/Chipset/CPU.cpp:420
#7  0x0000558e84f8443e in casioemu::Chipset::Tick (this=0x558e86f471a0) at emulator/Chipset/Chipset.cpp:307
#8  0x0000558e84f76bd8 in casioemu::Emulator::Tick (this=0x7fff65816d10) at emulator/Emulator.cpp:370
#9  0x0000558e84f76737 in casioemu::Emulator::TimerCallback (this=0x7fff65816d10) at emulator/Emulator.cpp:304
#10 0x0000558e84f74324 in operator() (__closure=0x558e87562248) at emulator/Emulator.cpp:110
#11 0x0000558e84f77c16 in std::__invoke_impl<void, casioemu::Emulator::Emulator(std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&, bool)::<lambda()> >(std::__invoke_other, struct {...} &&) (__f=...) at /usr/include/c++/13.2.1/bits/invoke.h:61
#12 0x0000558e84f77bd9 in std::__invoke<casioemu::Emulator::Emulator(std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&, bool)::<lambda()> >(struct {...} &&) (
    __fn=...) at /usr/include/c++/13.2.1/bits/invoke.h:96
#13 0x0000558e84f77b86 in std::thread::_Invoker<std::tuple<casioemu::Emulator::Emulator(std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&, bool)::<lambda()> > >::_M_invoke<0>(std::_Index_tuple<0>) (this=0x558e87562248) at /usr/include/c++/13.2.1/bits/std_thread.h:292
#14 0x0000558e84f77b5a in std::thread::_Invoker<std::tuple<casioemu::Emulator::Emulator(std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&, bool)::<lambda()> > >::operator()(void) (this=0x558e87562248) at /usr/include/c++/13.2.1/bits/std_thread.h:299
#15 0x0000558e84f77b3e in std::thread::_State_impl<std::thread::_Invoker<std::tuple<casioemu::Emulator::Emulator(std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&, bool)::<lambda()> > > >::_M_run(void) (this=0x558e87562240) at /usr/include/c++/13.2.1/bits/std_thread.h:244
#16 0x00007f188c8e1943 in std::execute_native_thread_routine (__p=0x558e87562240) at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:104
#17 0x00007f188c6a955a in ?? () from /usr/lib/libc.so.6
#18 0x00007f188c726a3c in ?? () from /usr/lib/libc.so.6
bczhc commented 5 months ago

还有反汇编窗口不见了!

qiufuyu123 commented 5 months ago

pull一下,刚修

qiufuyu123 commented 5 months ago

然后内存编辑器内容好像修改不了?

bczhc commented 5 months ago

然后内存编辑器内容好像修改不了?

可以啊,直接打或直接ctrl-v

bczhc commented 5 months ago

键盘没什么问题,但我还是总觉得鼠标容易丢键,不知是不是点击事件处理方面的问题。

a.webm

看这个视频,能确定鼠标是点到位的,但计算器没反应。第一个片段是[S]8下27的7丢了,尤其是第二个,AC直接丢了,不知道为什么。看那个小窗口,显示x11的鼠标事件,(2423,1003)这个点就是最后一个AC没有响应。

qiufuyu123 commented 5 months ago

image 拉一下新的commit 我把时钟频率调高一点,试试看?可能会好一点

qiufuyu123 commented 5 months ago

这个也取决于模拟器模拟的时钟频率,要能跟得上按键事件的频率(模拟器的按键不是队列的形式,他是直接赋值给ki/ko的,所以如果两个按键按的太快,模拟器rom还没来得及在一个时钟周期内读取ki/ko,ki/ko会被下一个按键覆盖掉,就会丢键盘) 提高时钟频率会改善一点 🤔

bczhc commented 5 months ago

不太像是这个问题(而且感觉更卡了,,.)。先注意这个issue尤其指明的是鼠标操作,可以说只有鼠标操作才卡,键盘操作没明显卡顿。测试的时候都用鼠标点击。

它那些按键在点击时都是有个反馈的嘛,颜色会变深。如果把DebugUi去掉,那些反馈都是即时的。如果真是某个键按得很快,比如快速双击菜单键,它只弹出菜单但没关闭,这应该就是“显示菜单”这个操作需要的时钟周期多一些,紧接着的“关闭菜单”没等“显示菜单”操作完全执行完就按下了,导致被忽略,这也正常,但在UI方面那个反馈始终是即时的,“跟手”的。

而如果把DebugUi加上,按键反馈就感觉有延迟,不那么即时,甚至压根就无变深反馈。就像那个视频中。而且视频中丢掉的键也不太像“快速双击菜单”情况。我感觉这问题更是UI处理鼠标按键上的,不是模拟器上的。

qiufuyu123 commented 5 months ago

看一下这个 试试这个,双线程渲染,感觉好了一些 🤔

qiufuyu123 commented 5 months ago

https://github.com/qiufuyu123/CasioEmuNeo/assets/60765480/3e57e878-e3dd-4ebf-bdd8-85a68238f919

还有个神奇的问题,memedit修改不了 🤔

bczhc commented 5 months ago

还有个神奇的问题,memedit修改不了 🤔

哪个commit?

qiufuyu123 commented 5 months ago

目前最新commit,但是之前应该就存在了,没注意

bczhc commented 5 months ago

没有任何问题。测试commit 098aa9c6120e8fba3b5d0252a6b3dd7dc4f79936

a.webm

qiufuyu123 commented 5 months ago

没有任何问题。测试commit 098aa9c

等会,视频在准备

难道是跟平台有关

bczhc commented 5 months ago

这怎么会跟平台有关呢。要不,bisect一下看哪个commit引入的😂

bczhc commented 5 months ago

测试了,最新commit点击是一点不卡了。可以算是解决了吧。(就是好像DebugUi又有点卡了。。这个无所谓吧,模拟器操作流畅就好

qiufuyu123 commented 5 months ago

我跟你用同样的commit跑出来,我的会出现上面视频上的情况

qiufuyu123 commented 5 months ago

image 定位到了,strtoul始终返回 0 image 尽管strbuf有值

bczhc commented 5 months ago

诶,所以为什么呢

bczhc commented 5 months ago

https://github.com/qiufuyu123/CasioEmuNeo/blob/098aa9c6120e8fba3b5d0252a6b3dd7dc4f79936/emulator/casioemu.cpp#L171

我试了,两个线程,这个sleep去掉模拟器也完全没有卡顿感。50ms有点太大了,真要加16ms也差不多了,60帧每秒嘛就是16ms。

qiufuyu123 commented 5 months ago

ok破案了 image image 应该是mingw的gcc版本有点低,这里没办法识别为3个char的数组,得手动设置下长度

bczhc commented 5 months ago

sleep可完全去掉了,本身就是一个UI main looper。至于程序始终要吃一个CPU(100%)不是DebugUi的问题,把DebugUi一整个去掉都会100%。这个issue就可以结束了,

bczhc commented 5 months ago

啊这,哦哦,属于我写的bug了。。是应该以'\0'结束的。因为strtoul接受字符串,我忘以nul结尾了。