Most Memory Efficient c++11 (or higher) Compiler

Okay, so I am a perfectionist, so I NEED my applications to have INSANE performance (i.e. low usage of the computers resources which in this case is RAM). My goal is to make all of my applications be able to run in under 64Kb of memory if they need to (can't allocate any more memory). But, I ran into a major problem: I can't find any help pages on what compiler with what arguments to use. So, what would be a compiler that I can use to achieve these performance feats (please note that I do not use the terminal (DOS-like command prompt looking window) in my applications).

EDIT: To clarify the question; I am looking for a compiler that, when it compiles a c++ program that does not include any headers and no libraries are being linked, the resulting program uses up 0 bytes of RAM (or the smallest number of bytes possible).

EDIT #2: I know it is the year 2016, where computers have plenty of RAM to spare, so I am not very justified to be a RAM perfectionist freak, but anyhow that has absolutely nothing to do with the topic of discussion (also using less RAM is healthy for the environment because 'energy cannot be created or destroyed', so reading/writing RAM uses electricity (however small it may be)), so please don't post responses about it, please :)
Last edited on
Insane performance... by using your hard disk like a RAM?
Also, why such a low RAM requirement? Most PCs nowadays have 4GB, and 99% older PCs have at least 256MB.

Please also note that "Insane performance" and "run in under 64kb of memory" are mutually exclusive for Windows applications.
Thank you so much for your response SGH,

I removed the rest of the contents of this post because it was causing too many off-topic responces
Last edited on
Emphasize how I said 'if need-be'. I want my applications to be the most portable thing in the universe (like as portable as the laws of physics

Then you shouldn't be pretending it is always feasible to trade memory for disk space.


so I am planning to design my c++ applications to be able to see how much spare RAM the computer has and act accordingly,

You can't do that portably.


All of that would be for the sake of that (10^-15)% extra portability that I yearn and desperately crave for.

What I see is: "I want to reduce portability for the sake of a hypothetical, possibly unnoticeable gain in spatial efficiency, under the guise of increasing portability."

Good luck with that.

(The fact that you're making this post in the windows forum is just icing on the cake. But, you live in America. I guess you're free not to make too much sense.)
Last edited on
Thank you so much for your response cire, but as I said, this is really getting off topic, so please don't post more posts here unless they're about what this question is about which is the most memory efficient compiler.
Last edited on
what I mean by 'Insane performance' is good performance of the application because the application uses up very little of the computers resources (RAM).


But you will be writing to disk instead, which is incredibly slow. An application that uses the hard disk instead of RAM whenever possible will be horribly underperformant. There is a reason that computers only fall back to the hard disk paging files when they think they need to, and why CPUs have continually gotten more cache memory - speed.

I'm not sure how to reconcile your two goals of "low RAM usage by using the disk instead" and "fast/good performance".
Again, thank you very much for your response, but let's please try to stay on topic, please :)
Most if not all compilers have an option to optimize for executable size (Os on g++) but having 0 RAM usage is likely impossible, the executable itself will have a size > 0 and when run the executable is loaded into memory.
Its pretty much like naraku said above. RAM pretty much is where everything happens. You've gotta use some. On Windows systems every process started has to at least have the kernel32 library mapped into it. When a C/C++ program starts under Windows one of the 1st things that happens is that the C/C++ runtime is initialized and loaded, and that takes a lot of RAM.

That can be controlled though. You might be interested in some work I'm doing here...

http://www.jose.it-berater.org/smfforum/index.php?topic=5102.0

where I'm eliminating the loading of the C runtime. The original inspiration of this work goes all the way back to the late 1990s when Matt Pietrek, who used to write for Microsoft Systems Journal, created his own version of the C Runtime he named LibCTiny.lib. Working off his original concept I've been able to update it to x64 with UNICODE supoort and I can create a "Hello, World!" console app in 2,560 bytes or a Windows GUI program in 3,072 bytes with no additional runtime support needed with the latest Microsoft compiler - VC 19 (from Visual Studio 2015). I've written my own stripped down versions of the C and C++ libraries, and I use those instead. In terms of program size, you can't use anything from the C++ Standard Library without having your program become typical modern bloatware.

Last edited on
'course, you could always write in assembler. But I don't see a whole lot of sense in that cuz its too difficult to do floating point math jiggling bits around in different registers. C and C++ on the other hand at least handle expression evaluation. And anyway, even in assembler you can't get program sizes down much if any from what I just mentioned above, which is achievable in C++ where you have the advantages of classes and much more.
You need assembler ,not C for that But i doubt that you really gain whatsoever
Thank you so much, you are absolutely correct. The reason I need the compiler to be for c++ is because I am using c++ as my bridge language to lower level languages such as assembly and eventually bytecode, so I need the compiler to be for c++. Also, I am not looking for a C++ compiler more efficient than is possible (because that would be impossible), but rather the most efficient c++ compiler that is possible that exists.
Last edited on
@ OP: You're going about this all wrong, the page allocation size isn't up to the compiler or the code. It's dependent on the architecture of the CPU. For example, the most common one, x86-64, has a minimum page allocation size of 4 KB. This means you cannot have a section of memory smaller than 4KB allocated to your program no matter how small or efficient your code is. If you want to know what the minimum page size is on the computer you are running then run this code:

1
2
3
4
5
6
7
int main()
{
      SYSTEM_INFO SI;
      GetSystemInfo(&SI);

      std::cout << SI.dwPageSize;
}


Add to that the fact that Windows automatically injects kernel32.dll into every running process, and user32.dll into every user space process, and you have a fixed overhead that basically destroys what you are trying to do.

Also the standard file format, PE32, introduces a certain amount of overhead through page alignment which is up to the linker, not you. If your code is not in this format then Windows will not run it. This is the same format used in stub files like DLL's too so don't think that you can get around it by doing that.

These are just the reasons off the top of my head for why you can't actually accomplish this goal of minimizing your memory footprint. I'm sure there are more.
Last edited on
Right on Computergeek. Using VC's /nodefaultlib capabilities one can get away from the loading of anything into memory except for kernel32. In that way the elimination of the C Runtime saves a lot. From my link above I can compile this to 2560 bytes...

1
2
3
4
5
6
7
8
9
10
// cl Ex01.cpp /O1 /Os /GS- /link TCLib.lib kernel32.lib
#define UNICODE         // 2,560 bytes x64 UNICODE
#define _UNICODE
#include <windows.h>
#include "tchar.h"

int _tmain()
{
 return 0;
}


The 2560 bytes is the size of the compiled code, but like you said it'll take 4 k on disk or loaded into memory. I do believe that number above to be rock bottom - at least for a program sporting a main() method.

Coding one's own printf from procedures in kernel32 one can manage this..

1
2
3
4
5
6
7
8
9
10
11
12
// cl Ex02.cpp /O1 /Os /GS- /link TCLib.lib kernel32.lib
#define UNICODE          // 3,072 bytes x64 UNICODE
#define _UNICODE
#include <windows.h>
#include "stdio.h"
#include "tchar.h"

int _tmain()
{
 _tprintf(_T("Hello, World!\n"));
 return 0;
}


So we're now up to 3072. By the way, here is what the printf looks like I'm using. Its based on Matt Pietrek's work from Microsoft Systems Journal. I added the wide character support...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//=====================================================================================
//               Developed As An Addition To Matt Pietrek's LibCTiny.lib
//                            By Fred Harris, January 2016
//
//                    cl printf.cpp /GS- /c /W3 /DWIN32_LEAN_AND_MEAN 
//=====================================================================================
#include <windows.h>
#include <stdarg.h>
extern "C" int __cdecl  printf(const char*    format, ...);
extern "C" int __cdecl wprintf(const wchar_t* format, ...);
#pragma comment(linker, "/defaultlib:user32.lib")  // Force the linker to include USER32.LIB


extern "C" int __cdecl printf(const char* format, ...)
{
 char szBuff[1024];
 DWORD cbWritten;
 va_list argptr;
 int retValue;
          
 va_start(argptr, format);
 retValue = wvsprintf(szBuff, format, argptr);
 va_end(argptr);
 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), szBuff, retValue, &cbWritten, 0);

 return retValue;
}


extern "C" int __cdecl wprintf(const wchar_t* format, ...)
{
 wchar_t szBuffW[1024];
 char szBuffA[1024];
 int iChars,iBytes; 
 DWORD cbWritten;
 va_list argptr;
           
 va_start(argptr, format);
 iChars = wvsprintfW(szBuffW, format, argptr);
 va_end(argptr);
 iBytes=WideCharToMultiByte(CP_ACP,0,szBuffW,iChars,szBuffA,1024,NULL,NULL);
 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), szBuffA, iBytes, &cbWritten, 0);

 return iChars;
}


Finally, for GUI Windows we're actually still at only 3,072 bytes, even with VC from Visual Studio 2015 in x64 UNICODE...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// cl Form1.cpp /O1 /Os /GS- /link TCLib.lib kernel32.lib user32.lib gdi32.lib 
// 3,072 Bytes x64 UNICODE
#define UNICODE   // /entry:wWinMainCRTStartup
#define _UNICODE
#include <windows.h>
#include "tchar.h"

LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 if(msg==WM_DESTROY)
 {
    PostQuitMessage(0);
    return 0;
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevIns, LPTSTR lpszArgument, int iShow)
{
 WNDCLASSEX wc={};
 MSG messages;
 HWND hWnd;

 wc.lpszClassName = _T("Form1");
 wc.lpfnWndProc   = fnWndProc;
 wc.cbSize        = sizeof(WNDCLASSEX);
 wc.hInstance     = hInstance;
 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,_T("Form1"),_T("Form1"),WS_OVERLAPPEDWINDOW|WS_VISIBLE,200,100,325,300,HWND_DESKTOP,0,hInstance,0);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


These kinds of numbers are like 30 times or so smaller than with traditional setups, and are just about as small as you are going to get (If that sounds a bit like a taunt, it is. If anyone can do better I'd like to know how you did it).
Last edited on
Topic archived. No new replies allowed.