VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

When I try to run it on Android, it's very slow (+16000 cycles/second, supposed to be ~4770000/second (14318180/4/second to be exact). Is this simply because of it's 0ns delays every few cycles? (Source code in dignature) Is there a good way to profile on Samsung Galaxy S7 w/ Android NDK (Windows)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 13, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

What ARM CPU do you have in that? Take a look at this (I know nothing about Android, I am more of an iOS guy, so this might not work) http://www.pixelbeat.org/programming/profiling/

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 2 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

It uses a Samsung Exynos 8890 Octa CPU(Android) as far as I know(clocked at 2.4GHz). I'm trying to get the android-ndk-profiler to compile, but it just won't take the NDK_MODULE_PATH I pass to the ndk-build.cmd. I execute "androidprompt.bat profile" in the Windows command prompt(or through shortcut), resulting in the following output:

Profile build selected.
Android NDK: jni/src/Android.mk: Cannot find module with tag 'android-ndk-profiler' in import path
Android NDK: Are you sure your NDK_MODULE_PATH variable is properly defined ?
Android NDK: The following directories were searched:
Android NDK:
jni/src/Android.mk:46: *** Android NDK: Aborting. . Stop.

I have the contents of the android-ndk-profiler repository(https://github.com/richq/android-ndk-profiler ) downloaded into the "C:\androiddevdir\android-ndk-r12b\sources\android-ndk-profiler" directory and compiled by CD-ing into it from within the androidprompt.bat, then calling ndk-build to compile it. It generates two .a libraries in it's obj subfolders. Then I just plainly call the androidprompt.bat like described above, from the UniPCemu repository directory.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 13, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

Ah I see why at 2.4Ghz you are worried that you are only getting 16k cycles/sec. However keep in mind that unlike the desktop CPUs where you can trust the frequency on mobile ARM you will be dutycycled and probably you will not be running at 2.4Ghz all the time. That being said you should be getting way more than that. On my Raspberry PI 3 (which runs an ARM v8 at 1.2Ghz) I get about 2.9mil cycles/seconds in CAPE.

I do not know anything about NDK profiler but it just seem you are missing some paths so the projects find each other.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 4 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

Well, that's the strange thing: I specify the report path (C:/androiddevdir/android-ndk-r12b/sources or it's subdirectory makes no difference), but it refuses to find it.
Specifying an invalid path makes it throw a warning that it's ignoring the invalid import path(e.g. adding xxx to test to the end of the NDK_MODULE_PATH environment variable). It should show up at the line above the final line in my last post (the list of searched paths), but it doesn't even list it?

Batch file executed (the %1 if is executing ndk-build):

@echo off
set ANDROIDNDK=C:/androiddevdir/android-ndk-r12b
set path=%path%;%ANDROIDNDK%;C:\androiddevdir\apache-ant-1.9.7\bin;C:\androiddevdir\android-sdk-windows\platform-tools
rem Add Java path as well to support keytool.
set path=%path%;c:\Program Files\Java\jre1.8.0_91\bin
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_102
set ANDROID_HOME=C:/androiddevdir/android-sdk-windows
set NDK_MODULE_PATH=%ANDROIDNDK%/sources/android-ndk-profiler
rem Set us up in the used project folder and start a command line session to work in!
cd android-project
if "%1"=="profile" ndk-build profile=%ANDROIDNDK% NDK_MODULE_PATH=%NDK_MODULE_PATH%
cmd
pause

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 13, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

According to this (http://stackoverflow.com/questions/26662264/c … ath-android-ndk) the very last post mentions that the ACTUAL module was not in the /sources/ file and he had to move it there.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 6 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've managed to make it continue compiling up until it tries to compile GPU_mcount.S(with a lot of compiler errors):

[arm64-v8a] Compile        : android-ndk-profiler <= gnu_mcount.S
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S: Assembler messages:
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:11: Error: unknown pseudo-op: `.thumb_func'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:16: Error: unknown mnemonic `push' -- `push {r0-r3}'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:17: Error: unknown mnemonic `push' -- `push {lr}'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:18: Error: operand 1 should be an integer register -- `ldr r0,[sp,#20]@r0=lr pushed by calling routine'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:19: Error: operand 1 should be an integer register -- `mov r1,lr@address of calling routine'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:21: Error: unknown mnemonic `pop' -- `pop {r2}@this routine115return address'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:22: Error: unknown mnemonic `pop' -- `pop {r0,r1}'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:23: Error: junk at end of line, first unrecognized character is `@'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:24: Error: operand 1 should be an integer register -- `ldr r3,[sp,#8]@r3=lr pushed by calling routine'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:25: Error: operand 1 should be an integer register -- `str r2,[sp,#8]@return address now last on the stack'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:26: Error: operand 1 should be an integer register -- `mov lr,r3@lr=caller115expected lr'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:27: Error: unknown mnemonic `pop' -- `pop {r2,r3}'
C:/androiddevdir/android-ndk-r12b/sources/android-ndk-profiler/gnu_mcount.S:28: Error: unknown mnemonic `pop' -- `pop {pc}@pop caller115expected r2,r3 and return'
make: *** [obj/local/arm64-v8a/objs/android-ndk-profiler/gnu_mcount.o] Error 1

Executing "ndk-build profile=%ANDROIDNDK%/sources" from the androidprompt.bat file. I've moved the android-ndk-profiler jni folder contents to it's parent folder(C:\androiddevdir\android-ndk-r12b\sources\android-ndk-profiler). It wouldn't even try to compile otherwise.

Could it be it's because it's trying to compile it for the arm64-v8a architecture as well, instead of just for armeabi and armeabi-v7a as it's Application.mk suggests(for which it's build)?

Edit: Modifying UniPCemu's Application.mk file to only support those two platforms instead of "all" makes it continue compiling and finish without errors. So it's indeed only supported when building for those two platforms only.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 7 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've just ran it on my Samsung Galaxy S7, but no gmon.out file is generated when i terminate the application(it's called in the source code, though).

Startup code:

	#ifdef NDK_PROFILE
setenv( "CPUPROFILE_FREQUENCY", "500", 1 ); // interrupts per second, default 100
monstartup("libmain.so");
is_monpendingcleanup = 1; //We're running to allow pending cleanup!
#endif

After callback initialization:

	#ifdef NDK_PROFILE
atexit(&monpendingcleanup); //Cleanup function! We have lower priority than the callbacks(which includes SDL_Quit to terminate the application, which would prevent us from cleaning up properly.
#endif

Cleanup function:

#ifdef NDK_PROFILE
byte is_monpendingcleanup = 0; //Are we still pending cleanup?
void monpendingcleanup()
{
lock(LOCK_PERFMON); //Lock us!
if (is_monpendingcleanup) //Pending cleanup?
{
is_monpendingcleanup = 0; //Not pending anymore!
moncleanup();
}
unlock(LOCK_PERFMON); //Release us! We're finished!
}
extern char UniPCEmu_root_dir[256]; //Our root directory to use!
#endif

Before starting the main loop:

	#ifdef NDK_PROFILE
char gmonoutpath[256]; //GMON.OUT path!
memset(&gmonoutpath,0,sizeof(gmonoutpath)); //Init!
strcpy(gmonoutpath,UniPCEmu_root_dir); //Init to root dir!
strcat(gmonoutpath,"/gmon.out"); //Our output filename in our application directory!
setenv("CPUPROFILE",gmonoutpath,1); //Set the correct filename to output!
#endif

External definition:

#ifdef NDK_PROFILE
extern void monstartup(char const *);
extern void moncleanup();
#endif

All in main.c.

The gmon.out should be in the currently used UniPCemu root directory, as specified by the first writable drive of the SECONDARY_STORAGE environment(highest priority) then either SDCARD(Pelya's SDL and normal SDL(2)) and finally(for normal SDL(2) only) SDL_AndroidGetExternalStoragePath and SDL_AndroidGetInternalStoragePath. Since it's properly using the internal memory folder(where all documents are to make it run, including the used SETTINGS.DAT) exist, I conclude it's using the internal Samsung memory storage location correctly. But no gmon.out appears in that location, so there might be something wrong with either UniPCemu's code or the android-ndk-profiler itself?

Edit: Does the SDL_QUIT event fire when it's terminated using Android(goto task switch overview using the phone button(on Galaxy S7 left to the home button, or holding the home button on some systems, like my LG-P710), and terminating the app by swiping it off the screen or pressing X)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 8 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

I just found out something: triggering UniPCemu's RALT-F4 termination shortcut makes it handle the termination the emulator way, triggering SDL_QUIT event and emulator shutdown properly, logging the gmon.out file in the project's used directory.

So for some reason, the SDL_QUIT event(or SDL Terminating event) isn't properly called on Android, causing the app to be terminated by Android itself, instead of through the proper SDL_QUIT hander in UniPCemu's input.c. Thus terminating the app without properly cleaning up(and generating gmon.out).

The good news is, that it now properly generates a gmon.out to inspect:D

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

After adding a seperate batch file for analyzing the results from the profiling run(and looking at the resulting data), it seems the main problem is the text surface renderer itself: this takes up most of the CPU time. CPU_initLookupTables can be ignored(it's only called once when emulation of a certain CPU is started to precalculate all required lookup tables).

  %   cumulative   self              self     total           
time seconds seconds calls s/call s/call name
68.25 33.73 33.73 1953 0.02 0.02 GPU_textrenderer
23.39 45.29 11.56 4 2.89 2.89 CPU_initLookupTables
5.67 48.09 2.80 220911188 0.00 0.00 put_pixel
0.95 48.56 0.47 937440 0.00 0.00 filledmem
0.40 48.76 0.20 223720907 0.00 0.00 get_pixelrow_pitch
0.12 48.82 0.06 2425327 0.00 0.00 matchptr
0.08 48.86 0.04 4010040 0.00 0.00 filledchannelbuffer
0.06 48.89 0.03 4883942 0.00 0.00 readfifobuffer16
0.06 48.92 0.03 4034472 0.00 0.00 mixchannel
0.06 48.95 0.03 2444484 0.00 0.00 movefifobuffer16
0.06 48.98 0.03 2422394 0.00 0.00 memprotect
0.06 49.01 0.03 75343 0.00 0.00 updateAudio
0.06 49.04 0.03 75017 0.00 0.00 update8042
0.04 49.06 0.02 4358455 0.00 0.00 movefifobuffer32

So this code is probably the main culprit to it being so slow:

uint_64 GPU_textrenderer(void *surface) //Run the text rendering on rendersurface!
{
if (unlikely(allcleared)) return 0; //Abort when all is cleared!
uint_32 *renderpixel;
byte *xfont, *xchar;
if (__HW_DISABLED) return 0; //Disabled!
if (!memprotect(surface,sizeof(GPU_TEXTSURFACE),"GPU_TEXTSURFACE")) return 0; //Abort without surface!
if (!rendersurface) return 0; //No rendering surface used yet?
uint_32 color;
INLINEREGISTER word x,y;
INLINEREGISTER uint_32 notbackground; //We're a pixel to render, 32-bits for each 32 pixels!
INLINEREGISTER byte isnottransparent=0; //Are we not a transparent pixel(drawable)?
byte curchar=0; //The current character loaded font row!
int fx=0, fy=0, sx=0, sy=0; //Used when rendering on the screen!
#ifdef ADAPTIVETEXT
float relx=0.0, rely=0.0; //Relative X/Y position to use for updating the current pixel!
#endif
GPU_TEXTSURFACE *tsurface = (GPU_TEXTSURFACE *)surface; //Convert!

if (unlikely(tsurface->flags&TEXTSURFACE_FLAG_DIRTY)) //Redraw when dirty only?
{
WaitSem(tsurface->lock);

//First phase: get all pixels font/background status, by walking through the text!
x = y = 0; //Init coordinates!
xfont = &tsurface->fontpixels[0]; //The font pixels to use! as output!
xchar = &tsurface->text[0][0]; //The font pixels to use! as output!

do //Process all rows!
{
curchar = getcharxy_8(*xchar,y&7); //Get the current row to process!
//Process the entire row!
*xfont++ = (curchar&1); //Current pixel!
curchar >>= 1; //Shift next in!
*xfont++ = (curchar & 1); //Current pixel!
curchar >>= 1; //Shift next in!
*xfont++ = (curchar & 1); //Current pixel!
curchar >>= 1; //Shift next in!
*xfont++ = (curchar & 1); //Current pixel!
curchar >>= 1; //Shift next in!
*xfont++ = (curchar & 1); //Current pixel!
curchar >>= 1; //Shift next in!
*xfont++ = (curchar & 1); //Current pixel!
curchar >>= 1; //Shift next in!
*xfont++ = (curchar & 1); //Current pixel!
curchar >>= 1; //Shift next in!
*xfont++ = (curchar & 1); //Current pixel!
//Move to the next horizontal character!
++xchar; //Next character!
if (unlikely(++x == GPU_TEXTSURFACE_WIDTH)) //End of row reached?
{
x = 0; //Reset horizontal coordinate!
++y; //Goto Next row!
xfont = GPU_textget_pixelrowptr(tsurface,y); //Next row loaded!
xchar = &tsurface->text[y>>3][0]; //Next row loaded!
}
} while (likely(y != GPU_TEXTPIXELSY)); //Stop searching now!

//Second phase: update dirty pixels with their correct font/border/transparent color!
x = y = 0; //Init coordinates!
Show last 100 lines
		do //Process all rows!
{
updateDirty(tsurface,x,y); //Update dirty if needed!
if (unlikely(tsurface->notdirty[(y<<9)|x]!=TRANSPARENTPIXEL)) //Used pixel to render?
{
tsurface->notbackground[(y<<4)|(x>>5)] |= (1<<(x&0x1F)); //We're set!
}
else //Transparent pixel?
{
tsurface->notbackground[(y<<4)|(x>>5)] &= ~(1<<(x&0x1F)); //We're not set: we're transparent!
}
if (unlikely(++x==GPU_TEXTPIXELSX)) //End of row reached?
{
x = 0; //Reset horizontal coordinate!
++y; //Goto Next row!
}
} while (likely(y!=GPU_TEXTPIXELSY)); //Stop searching now!
tsurface->flags &= ~TEXTSURFACE_FLAG_DIRTY; //Clear dirty flag!
PostSem(tsurface->lock); //We're finished with the surface!
}

x = y = sx = sy = 0; //Init coordinates!
#ifdef ADAPTIVETEXT
relx = rely = 0.0f; //Init screen coordinate plotter!
#endif
if (unlikely(check_surface(rendersurface))) //Valid to render to?
{
renderpixel = &tsurface->notdirty[0]; //Start with the first pixel in our buffer!
notbackground = tsurface->notbackground[0]; //Are we not the background?
isnottransparent = (notbackground&1); //Are we a transparent pixel?
if (unlikely(isnottransparent)) //Color needed?
{
color = *renderpixel; //Init color to draw!
}
do //Process all rows!
{
if (unlikely(isnottransparent)) //The pixel to plot, if any! Ignore transparent pixels!
{
fx = sx; //x converted to destination factor!
if (tsurface->xdelta) fx += TEXT_xdelta; //Apply delta position to the output pixel!

fy = sy; //y converterd to destination factor!
if (tsurface->ydelta) fy += TEXT_ydelta; //Apply delta position to the output pixel!

put_pixel(rendersurface, fx, fy, color); //Plot the pixel!
}

#ifdef ADAPTIVETEXT
relx += render_xfactor; //We've rendered a pixel!
#endif
++sx; //Screen pixel rendered!
#ifdef ADAPTIVETEXT
for (;relx>=1.0f;) //Expired?
#endif
{
#ifdef ADAPTIVETEXT
relx -= 1.0f; //Rest!
#endif
++renderpixel; //We've rendered a pixel!
//Else, We're transparent, do don't plot!
if (likely(++x!=GPU_TEXTPIXELSX)) //End of row not reached?
{
if ((x&0x1F)==0) //To reload the foreground mask?
{
notbackground = tsurface->notbackground[(y<<4)|(x>>5)]; //Load the next background mask!
}
else
{
notbackground >>= 1; //Take the next pixel from the background mask!
}
}
else
{
x = sx = 0; //Reset horizontal coordinate!
#ifdef ADAPTIVETEXT
rely += render_yfactor; //We've rendered a row!
#endif
++sy; //Screen row rendered!
#ifdef ADAPTIVETEXT
for (;rely>=1.0;) //Expired?
#endif
{
#ifdef ADAPTIVETEXT
rely -= 1.0f; //Rest!
#endif
++y; //Next row to draw!
}
renderpixel = &tsurface->notdirty[y<<9]; //Start with the first pixel in our (new) row!
notbackground = tsurface->notbackground[y<<4]; //Load the new row's first foreground mask!
}
if (unlikely(isnottransparent = (notbackground&1))) //To render us?
{
color = *renderpixel; //Apply the new pixel to render!
}
}
} while (likely(y!=GPU_TEXTPIXELSY)); //Stop searching now!
}

return 0; //Ignore processing time!
}

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 10 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've optimized the text surface rendering by precalculating all horizontal and vertical(horizontal and vertical axis seperarated in two precalc buffers) locations of the screen, which maps the screen coordinates to the text surface coordinates. Now the GPU_textrenderer doesn't even show the GPU_textrenderer routine anymore(so it's either very light code now(only calculated once when starting the emulator), or it's nothing compared to the other routines that run(CPU_initLookupTables jumps to 100% CPU usage now, which should only be called once during the entire runtime of a running emulated CPU))?

Edit: With the latest optimizations, it's now running at ~26500 cycles/second(8088 at 4.77MHz, All sound hardware enabled(with AweROMGM soundfont), PSP-mode rendering(4:3 VGA, Color monitor, CGA emulation, rendering NTSC in old-style mode, Framerate disabled, Full CPU synchronization)).

The profiling itself reported fine, almost no time after 30 seconds of runtime:

Filename
profiler.txt
File size
173.02 KiB
Downloads
37 downloads
File comment
Profiler report by gprof(android-ndk-profiler) on Samsung Galaxy S7.
File license
Fair use/fair dealing exception

After a while it's 20000 cycles/S.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 11 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

I might have found a problem in the text surface rendering code, which may have been the cause of the extreme screen updates: it was checking the border of a character cell for updating clickable text(e.g. the Set button in the bottom right of the screen to open the Settings menu), but was comparing the old font with the newly set border, causing the text surface to always update each and every frame(60 times/second), instead of only once each frame(since it's only changing it's output once every second(framerate display) or when the user provides an action(e.g. like opening and using the settings menu or clicking the screen using the buttons(or keyboard/mouse input on PCs as well)).

Edit: The profile build is running like crazy, up to 260000 cycles/second now. Eventually jumps down to 5000-6000 cycles/second, though. Just from the text surface not updating as much(excess updating was being done, due to the update detection bug).

Edit: It takes about 24 seconds for it to drop from 270000(after optimizing the put_pixel and related subfunctions to be more efficient by using the (un)likely macros) to 5000-6000 seconds. So about 6480000 cycles emulated until it drops to almost nothing. So after about 0.736 seconds emulated, it shrinks down into nothingness(maybe the VGA starting or something related)?

The total profile time is about 52.7 seconds(calculating by dividing the GPU_textrenderer calls column by 60FPS, which is the rate the screen is drawn at).

Flat profile:

Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
64.52 40.53 40.53 3162 0.01 0.01 GPU_textrenderer
8.55 45.90 5.37 2 2.69 2.69 CPU_initLookupTables
2.04 47.18 1.28 97623048 0.00 0.00 put_pixel
1.64 48.21 1.03 604049 0.00 0.00 coreHandler
1.54 49.18 0.97 1517760 0.00 0.00 filledmem
1.24 49.96 0.78 9651478 0.00 0.00 updateVGA
0.99 50.58 0.62 28954434 0.00 0.00 VGA_SIGNAL_HANDLER
0.75 51.05 0.47 9429971 0.00 0.00 CPU_exec
0.70 51.49 0.44 9651478 0.00 0.00 tickPIT
0.60 51.87 0.38 28698357 0.00 0.00 video_updateLightPen

Full log:

Filename
profiler.txt
File size
397.77 KiB
Downloads
38 downloads
File comment
Full Android profiling log on the Samsung Galaxy S7.
File license
Fair use/fair dealing exception

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 12 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've modified the rendering code to precalc the start of the row to render on the rendering surface, avoiding multiplications every pixel, reducing it to once every scanline(on the main rendering surface rendered to SDL, which is flipped into view(forced update actually, using the custom 'flip' function in UniPCemu's GPU unit, SDL-to-SDL2-style, based on the way documented on the SDL migration tutorial on libsdl.org). So instead of calculating a pixel row every pixel, it's now done once every row, with the call to the put_pixel function removed(it's functionality copied and optimized).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 13 of 13, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've finally got it somewhat running at the same speed on a 2.2GHz laptop(Intel Dual core CPU). It runs at ~6% as well. I've managed to make it compile and start profiling with GCOV, but trying to convert the profiler dump to a text file seems to fail, asking for an unexistant data file?

I call "make win analyze lineprofile gcov_files=emu/gpu/gpu_text.c" to get results I need.

This literally executes "gcov emu/gpu/gpu_text.c". Anyone can see what's wrong about this?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io