The length section of the memory command in a linker file takes K, M symbols to indicate kilobytes, megabytes etc. Is the multiplier 1000 or 1024?
I know this is months later but I was wondering about the K and M parts myself.
The LD manual states that the expression "must be numerical only and evaluate to a constant". It then blithely proceeds to use an example of 256K and 4M which is slightly disconcerting!
The relevant source code files (in binutils/ld) appear to be ldlex.l and ldgram.y. In the lexer, an expression can end with [M|K|m|k].
For M or m, the value is multiplied by 1024 * 1024.
For K or k, the value is multiplied by 1024.
Edit: I had read sections of the LD manual in isolation, which can be misleading! When I read more of the linker manual, I can see that it does specify what it means by numerical constant, which does include suffixes like K and M:
https://sourceware.org/binutils/docs/ld/Constants.html#Constants
Related
I am analyzing the operation of the cache of a code and this question has arisen:
C[i] = B[i] + A[i];
G[i] = x*F[i];
This is the part of the code where I have the doubt. Context: my cache memory has space up to 4 of these 5 vectors. It works with a LRU algorithm (Least Recently Used) so C,B,A and F are stored with any problem, but G has no space in the cache so the vector that has not been used for the longest time is replaced with the vector values of G. Here are the questions:
Was A the first or was it B? What principle does the C compiler follow to make the decision of what element is first read? Does it depend on which compiler is used (GCC, ICC...) or do they all generally follow the same discipline?
In C[i] = B[i] + A[i]; the compiler may load A[i] first or B[i] first. The C standard does not impose any requirement on this ordering.
With G[i] = x*F[i]; coming after that, the compiler must load F[i] after storing C[i] unless it can determine that F[i] is not the same object as C[i]. If it can determine that, then it may load A[i], B[i], and F[i] in any order.
Similarly, if it can determine that G[i] does not overlap C[i], it may store C[i] and G[i] in either order.
If this code appears in a loop, this permissive reordering extends to elements between iterations of the loop: If the compiler can determine that it will not affect the defined results, it can load B[i] from a “future” iteration before it loads A[i] for the current iteration, for example. It could load four elements from B, four elements from A, four elements from F, and do all the arithmetic before it stores any elements to C or G. (Often the compiler does not have the necessary information that the arrays overlap, so it will not do this reordering unless you give it that information in some way, as by declaring the pointers with restrict or use special pragmas or compiler built-ins to tell it these things.)
Generally, the C standard is permissive about how actual operations are ordered. It only mandates that the observable behavior it specifies be satisfied. You should not expect that any particular elements are loaded first based on standard C code alone.
Is there any limit as to how many elements a 2D integer array can contain in C?
PS : I was expecting there would be some space limitations in declaring an array but could not find any such reference in the internet.
It depends on your RAM or the memory available for you.
i:e: My program used to crash when I declared a global array a[100000][10000], but this declaration is fine with the system now I have.
The size_t type is defined to be large enough to contain the size of any object in the program, including arrays. So the largest possible array size can be described as 2^(8*sizeof(size_t) bytes.
For convenience, this value can be obtained through the SIZE_MAX constant in limits.h. It is guaranteed to be at least 65535 but is realistically a larger value, most likely 2^32 on 32 bit systems and 2^64 on 64 bit systems.
Maximum imposed by the C/C++ standard: x * y * z <= SIZE_MAX, where SIZE_MAX is implementation defined, x is one dimension of the array, y is the other dimension, and z is the size of the element in bytes. e.g. element_t A[x][y], z = sizeof(element_t).
Sorry if this is not the correct place to do this question, this is not about programation instead is a technical question.
I need to work with enormous size arrays of 2D vectors in double precision, 10 million of them aproximately. But, in other programs I had memory problem in deal with this kind of arrays. My question is if there is some kind of limit for the array size in double precision.
I work in Linux, Intel two core, 32-bits.
thanks
Ok, I will explain by why the number of bytes is limited, not only the element count. During array indexing, the address of the element must be calculated. Of course it must fit to the intptr_t C variable. Also, the size of the array in bytes must fit in a size_t C variable. These are both 32-bit or 64-bit on 32-bit and 64-bit programs on modern machines. The same also holds for the virtual memory addressable by program! And also the memory addressable by the OS and CPU, though they can be 64-bit even if the program is 32-bit.
This is the fundamental reason why 32-bit programs and operating systems cannot address more than 4 GB of memory. Even if you could somehow compute the address using a Fortran variable wider than the chosen CPU word size, the CPU simply cannot access it.
Finally I mad an experiment in Intel Fortran in 32-bit mode with array with 32 byte elements:
complex(16), allocatable :: a(:)
do i=1,100
allocate(a(2**i))
a(size(a)) = 1
deallocate(a)
write(*,*) i
end do
end
ifort arraysize.f90 -m32 -check -traceback -g
The output is as expected:
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
forrtl: severe (179): Cannot allocate array - overflow on array size calculation.
As expected the size of the array in bytes overflowed and the program crashed long before the indexing variable overflowed. This is not a compiler specific feature, but there is a fundamental reason for this.
The Fortran language standards don't define a limit to the size of arrays that a program can (attempt to) declare or allocate. In practice you may find that your compiler limits the total number of elements in an array to 2^31-1 or 2^63-1, depending on whether your default integer size is 32- or 64-bits. You may find that the maximum size of any dimension of an array is also limited to the same values.
In practice the maximum size of array that you can declare will be limited by the RAM available on your computer. Since a double precision value occupies 8 bytes it's relatively easy for you to calculate the maximum bounds of arrays that you are likely to be able to work with. Any storage overhead required for an array is tiny compared with the volumes of data you seem to want to work with.
In response to VladimirF's comments
I meant, and still mean, the number of elements, not the number of bytes. It is the number of elements which determines the maximum index value required to access an element of an array.
It may be that some compilers impose a limit to the number of bytes used in a single array, but that is not a point I am making.
Fortran arrays can, of course, be indexed from 0, indeed from any positive or negative integer within range, but that is really just a convenience for the programmer.
In zlib 1.2.7, file inffast.c, line 320, there is a statement that I do not understand:
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
Variables end and out are two pointers into the output buffer.
This statement makes an effort to compute end - out when end > out and out - end when out >= end, but I do not see why it might want to do that. It seems to me that the end result is the same, that is, the line might as well have been written:
strm->avail_out = 257 + (end - out);
The difference of two pointers has a signed integral type, ptrdiff_t (C99 6.5.6:9), and 257 has type int. The addition takes place in the type of higher rank between these two, and I do not see what the ternary operator could possibly be guarding against.
Your observation is correct for C99 as well as C89/C90.
That line of code was written ten years ago. At this point my memory permits me only to be able to claim paranoia as the excuse. Apparently I was concerned that in some compilers the result of subtracting two pointers might be unsigned. I do not recall the origin of that concern, or if it had any basis at all.
As for the change history, that line of code was born from the brow of Zeus as you see it today. It has not been changed since it was written.
The Fortran reference implementation documentation states:
* LDA - INTEGER.
* On entry, LDA specifies the first dimension of A as declared
* in the calling (sub) program. When TRANSA = 'N' or 'n' then
* LDA must be at least max( 1, m ), otherwise LDA must be at
* least max( 1, k ).
* Unchanged on exit.
However, given m and k shouldn't I be able to derive LDA? When is LDA permitted to be bigger than n (or k)?
The LDA parameter in BLAS is effectively the stride of the matrix as it is laid out in linear memory. It is perfectly valid to have an LDA value which is larger than the leading dimension of the matrix which is being operated on. Typical cases where it is either useful or necessary to use a larger LDA value are when you are operating on a sub matrix from a larger dense matrix, and when hardware or algorithms offer performance advantages when storage is padded to round multiples of some optimal size (cache lines or GPU memory transaction size, or load balance in multiprocessor implementations, for example).
The distinction is between the logical size of the first dimensions of the arrays A and B and the physical size. The first is the size of the array that you are using, the second is the value in the declaration, or the physical amount of memory used. Since Fortran is a column major language, the declared sizes of all indices except the last must be known in order to calculate the location of an array element. Notice the FORTRAN 77 style declarations of "A(LDA,),B(LDB,),C(LDC,*)". The declared size of the array can be larger than the portion that you are using; of course it can't be smaller.
Another way to look at it is LDA is the y-stride, meaning in a row-major layout your address for element A[y,x] is computed as x+LDA*y. For a "packed" memory layout without gaps between adjacent lines of x-data LDA=xSize.