How to Calculate FAT - fat

I am learning about FAT file system and how to calculate FAT size. Now, I have this question:
Consider a disk size is 32 MB and the block size is 1 KB. Calculate the size of FAT16.
Now, I know that to calculate it, we would multiply the number of bits per entry with the number of blocks.
So first step would be to calculate the number of blocks = (32MB)/(1KB) = 2^15 = 32 KB blocks.
Then, we would put that into the first equation to get = 2^16 * 2^15 = 2^19
Now, up to here I understand and I had thought that that is the answer (and that is how I found it to be calculated in http://pcnineoneone.com/howto/fat1.html).
However, the answer I was given goes one step further to divide 2^19 by (8*1024) , which would basically give an answer of 64KB. Why is that? I have searched for hours, but could find nothing.
Can someone explain why we would perform the extra step of dividing 2^19 by (8*1024)?
oh, and the other question stated that the block size is 2KB and so it divided the end result by(8*1024*1024) ... where is the 8 and 1024 coming from?
please help

you are using FAT16. Clusters are represented with 16 bits which means 16/8=2 bytes. To get size in bytes the result should be divided by 8.to get result in kilobytes you should divide your result by 8*1024

Related

What is the advantage of this sizing code in C?

Apologies for the generic question title, I wasn't sure how to phrase it properly (suggestions welcome!)
I'm trying to get my head around some of the code for the Common Mark parser and came across this:
/* Oversize the buffer by 50% to guarantee amortized linear time
* complexity on append operations. */
bufsize_t new_size = target_size + target_size / 2;
new_size += 1;
new_size = (new_size + 7) & ~7;
So given a number, eg 32, it will add (32 / 2) [48], add 1 [49], add 7 [56], finally ANDing that with -8 [56].
Is this a common pattern? Specifically the adding of a number and then ANDing with its complement.
Is anyone able to provide any insight into what this is doing and what advantages, if any, exist?
The (+7) & ~7 part rounds the number up to the first multiple of 8. It works only with powers of 2 (7 is 2^3-1). If you want to round to a multiple of 32 then use 31 instead of 7.
The reason to round the size to a multiple of 8 is probably specific to the algorithm.
It is also possible that the author of the code knows how the memory allocator works. If the allocator uses internally blocks of memory of multiple of 8 bytes, an allocation request of any number of bytes between 1 and 8 uses an entire block. By asking for a block having a size that is multiple of 8 one gets several extra bytes for the same price.

how the ping implementation calculating the round trip time?

I was learning about the ping implementation.
In that I had one doubt. The doubt is, how they calculating the round trip time.
They done some calculation to calculate the round trip time. I am not able to understand that calculation.
Here is the code for the round trip time calculation.
tsum += triptime;
tsum2 += (long long)triptime * (long long)triptime;
if (triptime < tmin)
tmin = triptime;
if (triptime > tmax)
tmax = triptime;
if (!rtt)
rtt = triptime*8;
else
rtt += triptime-rtt/8;
The tsum, tsum2, triptime, tmax variables are initially 0.
The tmin contains the value as 2147483647 as initially.
The triptime is calculated by the before the packet sending, noted one time. In destination the packet is received, before it send replay it note one time and it fill that in reply packet and it sends the reply.
The two times are subtracted and convert that subtracted time into micro seconds. The triptime variable contains that micro seconds.
For example, take the below output for calculating the rtt.
The trip time for the first packet is 42573, and second packet 43707, third packet 48047, and fourth packet 42559.
Using this how they calculate the round trip time. Why they multiply with 8 in the starting and after that they divide with 8 and subtract with the first rtt. I am not able to find why they calculating the rtt like that.
Can any one please explain me why they multiply with 8 in starting and after that why they divide with 8 and subtract with the before calculated rtt.
The below link contains the full code for the ping implementation.
ping_common.c
ping.c
Thanks in advance.
rtt is Modified Moving Average of triptime values, multiplied by 8 for easy calculations, with N==8.
rtt in the program variable name is not necessarily rtt in the output - And here it isn't.
The 'average round trip delay' in the implementation you show is in tsum / count of packets. When you look at rtt, you are actually looking at something different. That is only displayed when you use pingin adaptive mode.
Because you are dealing with bits. Bit rate and transmission time are not the same thing, so you need to do a tiny bit of arithmetic to convert. The formula is:
Packet transmission time = Packet size / Bit rate
So assuming 100 Mbit/s and a packet size of 1526 bytes, you get:
1526 bytes x 8 bits / (100 x 106 bits/second)) = 116 microseconds
The bit unit cancels out and you are left with seconds.
Now here's another example. Say you have a round trip time of 225 milliseconds and your throughput is 32 kilobytes. You get:
32,000 bytes * 8 bits / 0.255 = 1,003,921 bits per second

Determining TASK_SIZE from c Program

TASK_SIZE is a kernel constant that defines the upper limit of the accessible memory for the code working at the lowest privilege level.
Its value is usually set to 0xc0000000 on systems with less than 1GB of physical memory (all examples included in this article refer to this value). The memory above this limit contains the kernel code .
Is there a way to determine the running kernels TASK_SIZE through c program ??
TASK_SIZE
After a lot of google search and analysis , i got a logic
Assume net virtual address are 4gb and the it is divided in 1:3 ratio.
Rough assumptions:-
Kernel (upper 1 gb): c0000000 -ffffffff
USer space (below 3gb):0-c0000000
than
#define GB *1073741824
unsigned int num;
unsigned int task_size;
task_size=(unsigned)&number+ 1 GB / 1 GB * 1GB;
[the process's stack area will be allocated below the kernel space]
so address of num (in stack)= somewhere around in 3 GB range ex:[3214369612]
now adding 1 GB = 1073741824+3214369612=4288111436
dividing by 1GB=3.993614983 that will be 3 (unsigned int)
now multiplying by 1GB = 3 *1073741824 = 3221225472 i.e. (0xC0000000 in hex)
hence i got the kernel starting address (TASK_SIZE)
I tried it assuming (2:6) ratio also and got correct result.
Is this a fair logic ,Please comment ???

Padding array manually

I am trying to understand 9 point stencil's algorithm from this book , the logic is clear to me , but the calculation of WIDTHP macro is what i am unable to understand, here is the breif code (original code is more than 300 lines length!!):
#define PAD64 0
#define WIDTH 5900
#if PAD64
#define WIDTHP ((((WIDTH*sizeof(REAL))+63)/64)*(64/sizeof(REAL)))
#else
#define WIDTHP WIDTH
#endif
#define HEIGHT 10000
REAL *fa = (REAL *)malloc(sizeof(REAL)*WIDTHP*HEIGHT);
REAL *fb = (REAL *)malloc(sizeof(REAL)*WIDTHP*HEIGHT);
original array is 5900 X 10000, but if i define PAD64 , the array
becomes 5915.75 X 10000
Though so far i can guess that the author is trying to align & pad array to 64 byte boundary. But array returned by malloc is usually aligned(& padded) , also, the posix_memalign gives you a chunk of memory that is guaranteed to have the requested alignment , we can also use
__attribute__((align(64)))
what impact does this WIDTHP can make on my code's performance?
The idea is that each row of the matrix (or column, if it's treated as a column-major matrix) can be aligned to the start of a new cache line, by adding padding to the end of the line. Exactly what impact this has depends of course a lot on the access pattern, but in general cache-friendliness can be quite important for intensely number-crunching code.
Also, the computation is integer, so the result is certainly not 5915.75, that doesn't make sense.
I was going to put this in as a comment to unwind's answer because he's right. But perhaps I can explain more clearly, albeit in more characters than will fit in a comment.
When I do the math, I get 5904 reals, which is 23616 bytes, which is 396 cache lines for 64 byte cache lines. It is the bytes, rather than the number of elements which must be a multiple of 64.
As to why you want to pad the value of width, lets look at a smaller example. Let's pretend we had a "cache line" that holds 10 letter and that we have an "array" with a width of 8 letters and height of 4. Now since our hypothetical array is in C and C is row major, the array will look something like this:
AAAAAAAA
BBBBBBBB
CCCCCCCC
DDDDDDDD
but what does it look like when it is arranged in cache lines, since those are 10 letters long:
AAAAAAAABB
BBBBBBCCCC
CCCCDDDDDD
DD
Not good. Only the first row of the array is aligned. But if we pad width by two spaces, we get this in cache:
AAAAAAAA__
BBBBBBBB__
CCCCCCCC__
DDDDDDDD__
which is what we want. Now we can have a nested loop like
for i = 1 to height
for j = 1 to width
and know that every time we start to work on the j loop, the data we need will be aligned.
Oh, and yes, they really should do something to make sure that the first element of the array is aligned. 'attribute((align(64)))' won't work because the arrays are being allocated dynamically but they could have used posix_memalign instead of malloc.
The width p calculation is say
( Width/64) +1
Well rounded for int precision math. I'd give you a better answer except in the SE mobile app it ain't viable to flick between this and the listing

find location from base address

So my computer science professor decided to ask us a question but gave no instruction on how to find the answer. The question is as follow:
Compute the location of the following elements, where the base address is FFFFFBACD:
A[4][6], A[5][5], A[2][7]
The array is declared as int [][]= new int [8][10]
He isn't asking us to program anything but just find the location. The issue I have is that the base address looks off and I have no idea how to do the calculation to find the answer. Any guidance would be greatly appreciated!!
Assuming your integers are 4 bytes each, then element [0][0] is at address FFFFFBACD.
The next element is [0][1] in a distance of 4 bytes, meaning: FFFFFBAD1.
Overall in each "row" you have 10 elements, thus 40 bytes. Therefore the address for [1][0] is FFFFFBACD + 40 bytes = FFFFFBAF5
Therefore, [4][6] will be 40*4 + 5*4 bytes from the start address: FFFFFBB85.
(note that here the number of rows is 4 and multiplies 40 bytes per row and the number of elements in the fifth row is 6 and each is 4 bytes long - these are different reasons for multiplying by 4).
Using this logic, try and find the other addresses. It shouldn't be that hard.

Resources