Maximum .PRG file size error

I am trying to recompile one Application from github from one watch model to another. When I build it I get this error

ERROR: PRG generated exceeds the memory limit of app type 'watch-app' for device id 'instinct2x': 218282 bytes.

What does it exactly mean? Is it max file size of prg file 218282 bytes or it is bigger than maximum allowed by 218282 bytes or what?

When I build it I get 363980 bytes prg file.

Can I find somewhere the list of max oprg files for each watch?

Also, how can I decrease the size of prg file? Maybe change SDK version or some compiler option?

  • I managed to run ciqdb to analyze prg file and it should that most of the space is used by code

    c0debabe - Code (202681 bytes) for instinct2

    c0debabe - Code (30228 bytes) for instinct3

    I am still wondering why code is much less for instinct3.

  • Thanks for sharing the code! It's a cool tamagotchi emulator for Garmin devices:

    https://github.com/Gualor/garmin-gotchi/ 

    I am still wondering why code is much less for instinct3.

    TL;DR I think CIQ 4 devices have better optimization and more efficient opcodes than CIQ 3 devices.

    I managed to run ciqdb to analyze prg file and it should that most of the space is used by code

    Yeah, so as I said, it seems like the code needs to be smaller to get it to work on instinct2x. Or to be more precise, the total amount of information in the PRG that's actually initially loaded into memory needs to be reduced - this includes both code and data (but not resources). Ofc it's probably not feasible to reduce the amount of data in the PRG unless you can move it to a JSON resource or something (but I don't think that would help in this case, since any large data that was hypothetically moved to JSON resources, such as TAMA_PROGRAM, would need to be loaded and kept in memory for the duration of the app's lifetime anyway.)

    Anyway, I did an additional test where I added an FR945LTE [which is CIQ 3.0, like instinct2x, but with more available memory than instinct2x for watchApp apps]

    For anyone else reading along, I should note that to add new devices to the project, you have to copy the resources-instinct3solar45mm folder to resources-DEVICE_ID (in this case, resources-fr945lte).

    I also want to note that the project monkey.jungle already has optimization enabled:

    project.optimization = 3p,enable-constant-folding,enable-empty-function-removal,enable-lexical-only-constants,enable-static-branch-elimination

    [I don't think anything after 3p is significant here, but I could be wrong]

    I think it would take a *lot* of work to find all the hand-optimizations you would need to get the code working on instinct2x tho. That assuming it's even possible.

    [1/x]

  • I ran the app in the sim for both instinct3solar45mm and fr945lte and found:

    - instinct3solar45mm: based on the memory viewer, the app code size is 29549 and the data size is 22052

    - fr945lte: based on the memory viewer, the app code size is 201720 and the data size is 15494. [The fr945lte version of the app does crash because the app calls getSubscreen[], which is obviously not available for non-instinct devices, but the memory viewer still works after the fact]

    I also tried building and running the instinct3solar45mm version with optimization set to 0. In this case, the app still builds, but it crashes with an out of memory error.

    I can only conclude that CIQ 4 devices support more efficient optimization / opcodes than CIQ 3 devices which leads to much smaller code sizes in some cases. It's pretty crazy that there's a roughly 7X difference in this case.

    I vaguely recall that members of the CIQ team may have mentioned something about newer devices supporting more efficient opcodes in the forums [maybe last year or so], but you also needed to use a newer SDK to support them.

    So I don't think you'll be able to get the app to run on instinct2x unless you manage to optimize the code by hand.

    [2/x]

  • And even if you're able to get the PRG small enough to avoid the compile time error you're seeing, that doesn't mean it won't run out of memory at run time.

    For example, as a test I got rid of the TAMA_PROGRAM array [and the code which uses it]. Obviously the app won't work this way, but I wanted to see what happens. In this case, the app builds for instinct2x, but it crashes with a runtime out of memory message at cpu_pvt.mc, at line 1480, which initializes a big data structure:

    [3/x]

  • If you can get rid of classes like Op, you could save a lot of memory at run time (objects, except for the "primitive" [*] types Number, Float, Long, Double, String, Boolean, and Null, have a huge amount of overhead), but that would be a ton of work. And that won't necessarily make your code smaller [which is something you also have to do, to get the PRG to be small enough in the first place]

    [*] yes I'm aware Monkey C doesn't really have primitives, but even the Monkey C docs sometimes refer to them as primitives, and they do have different properties than other objects, like immutability and lack of huge overhead

    Other things you can try:

    - Change switch statements to if-else statements

    - Manually fold duplicate code

    [4/4]

  • Thank you for your help. Yes, probably it will be easier to create it from scratch then trying to run that code.