Test Maximum Memory - eoredson - 04-26-2025
This code tries to assign a large arrays of memory..
If you have an upper range of memory, say, 32GB with 8GB free this may work:
In QB45 the "Out of memory" (error 7) would be displayed.
However, in QB64 the memory box will be displayed.
This the memory mem.h file:
Code: (Select All) //mem.h memory function library.
#include<windows.h>
#include<stdio.h>
#include<tchar.h>
uint64 MemInUsePercent();
uint64 TotalPhysicalMem ();
uint64 FreePhysicalMem ();
uint64 TotalPagingFile ();
uint64 FreePagingFile ();
uint64 TotalVirtualMem ();
uint64 FreeVirtualMem ();
uint64 FreeExtendedMem ();
static float CalculateCPULoad();
static unsigned long long FileTimeToInt64();
float GetCPULoad();
uint64 MemInUsePercent () {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.dwMemoryLoad;
}
uint64 TotalPhysicalMem () {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.ullTotalPhys;
}
uint64 FreePhysicalMem () {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.ullAvailPhys;
}
uint64 TotalPagingFile () {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.ullTotalPageFile;
}
uint64 FreePagingFile () {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.ullAvailPageFile;
}
uint64 TotalVirtualMem () {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.ullTotalVirtual;
}
uint64 FreeVirtualMem () {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.ullAvailVirtual;
}
uint64 FreeExtendedMem () {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.ullAvailExtendedVirtual;
}
static float CalculateCPULoad(unsigned long long idleTicks, unsigned long long totalTicks)
{
static unsigned long long _previousTotalTicks = 0;
static unsigned long long _previousIdleTicks = 0;
unsigned long long totalTicksSinceLastTime = totalTicks - _previousTotalTicks;
unsigned long long idleTicksSinceLastTime = idleTicks - _previousIdleTicks;
float ret = 1.0f - ((totalTicksSinceLastTime > 0) ? ((float)idleTicksSinceLastTime) / totalTicksSinceLastTime : 0);
_previousTotalTicks = totalTicks;
_previousIdleTicks = idleTicks;
return ret;
}
static unsigned long long FileTimeToInt64(const FILETIME & ft)
{
return (((unsigned long long)(ft.dwHighDateTime)) << 32) | ((unsigned long long)ft.dwLowDateTime);
}
float GetCPULoad()
{
FILETIME idleTime, kernelTime, userTime;
return GetSystemTimes(&idleTime, &kernelTime, &userTime) ? CalculateCPULoad(FileTimeToInt64(idleTime), FileTimeToInt64(kernelTime) + FileTimeToInt64(userTime)) : -1.0f;
}
This is the program:
Code: (Select All) Rem $Dynamic
Declare Library "mem"
Function FreePhysicalMem~&&
End Declare
Dim Memory2 As _Unsigned _Integer64
Dim Requested As _Unsigned _Integer64
_ScreenMove _Middle
Memory2 = FreePhysicalMem
Color 15
Print "Free Physical Memory:";
Print Using "###,###,###,###"; Memory2
x = 1024: y = 1024: z = 1024 ' array values
l = 2 ' length of int
Requested = 3 * x * y * z * l
Print "Requested Memory:";
Print Using "###,###,###,###"; Requested
If Requested > Memory2 Then
Color 12
Print "Not enough memory."
Color 7
End
End If
Color 14: Print "Requested memory array."
Dim z(x, y, z) As Integer
Dim z1(x, y, z) As Integer
Dim z2(x, y, z) As Integer
Color 14: Print "Requested memory assigned."
For i = 1 To 10
For j = 1 To 10
For k = 1 To 10
z(i, j, k) = i * j * k
Next
Next
Next
Erase z, z1, z2
Color 7
End
RE: Test Maximum Memory - mdijkens - 04-26-2025
Yes in QB64 you can use all your memory.
Compared to QB45 this can also lead to a different coding style
Where I used (random access) files a lot with QB45 to only keep data in memory that was processed at the time, now with QB64 you can most of the time read all data in memory at the start of your program and write it back when ending.
But despite the documentation
"Arrays in QuickBASIC 4.5 and QBasic are limited to 32767 elements, while arrays in QB64 are limited to 2147483647 elements (over 2 billion). When the 64-bit version of QB64 is implemented 9223372036854775807 elements will be the limit (but only on 64-bit systems)."
there are quite some issues with arrays above 2GB; some work up to 4GB, some up to 2GB while the doc says there should basically be no limit....
I'd love to see that fixed some day soon
But nothing stops you from using multiple 2GB arrays and unlimited _Mem as long as you have the physical memory available
RE: Test Maximum Memory - eoredson - 04-28-2025
With the advent of multi-terebyte ram configured motherboards (24xdimm 512GB.) or 12TB the following could be assigned:
Dim LargeArray(1024,1024,1024,1024) As Integer
for example. What I would like to know is if they require contiguous assignments or there is some sort of fragmented memory garbage collection?
So, here is a code snippet which tests ram starting from 1024x3 and downward in powers of 2 to 32x..
Code: (Select All) Rem $Dynamic
Declare Library "mem"
Function FreePhysicalMem~&&
End Declare
Dim Memory2 As _Unsigned _Integer64
Dim Requested As _Unsigned _Integer64
_ScreenMove _Middle
Memory2 = FreePhysicalMem
Color 15
Print "Free Physical Memory:";
Print Using "###,###,###,###"; Memory2
For q = 1 To 6
If q = 1 Then x = 1024: y = 1024: z = 1024: l = 2: GoSub assign
If q = 2 Then x = 512: y = 512: z = 512: l = 2: GoSub assign
If q = 3 Then x = 256: y = 256: z = 256: l = 2: GoSub assign
If q = 4 Then x = 128: y = 128: z = 128: l = 2: GoSub assign
If q = 5 Then x = 64: y = 64: z = 64: l = 2: GoSub assign
If q = 6 Then x = 32: y = 32: z = 32: l = 2: GoSub assign
Next
End
assign:
Requested = 3 * x * y * z * l
Color 15
Print "Assign"; x; "elements. Requested Memory:";
If q = 1 Then Print Using "###,###,###,###"; Requested
If q = 2 Then Print Using " ###,###,###"; Requested
If q = 3 Then Print Using " ###,###,###"; Requested
If q = 4 Then Print Using " ##,###,###"; Requested
If q = 5 Then Print Using " #,###,###"; Requested
If q = 6 Then Print Using " ###,###"; Requested
If Requested > Memory2 Then
Color 12
Print "Not enough memory."
Color 7
Return
End
End If
Color 14: Print "Requested memory array."
ReDim z(x, y, z) As Integer
ReDim z1(x, y, z) As Integer
ReDim z2(x, y, z) As Integer
Color 14: Print "Requested memory assigned."
For i = 1 To 10
For j = 1 To 10
For k = 1 To 10
z(i, j, k) = i * j * k
Next
Next
Next
Erase z, z1, z2
Color 7
Return
End
RE: Test Maximum Memory - DSMan195276 - 04-29-2025
In theory such large arrays should work, in practice it's not tested so your mileage may vary.
For your testing code, note that on Linux (and maybe Mac OS, not sure) the OS may not actually "give" you the memory until you write to it (more importantly, it may not actually be there to get ). You should access at least one byte per page on all three arrays to be sure it worked.
For actually allocating it, no the physical memory does not need to be contiguous for it to work. It's possible there are other OS limitations that will prevent you from doing it though.
|