0
votes

I try to write a data buffer into a file using write() system call on Linux, here is the user space code I wrote.

memset (dataBuffer, 'F', FILESIZE);
fp = open(fileName, O_WRONLY | O_CREAT, 0644);      
write (fp, dataBuffer, FILESIZE);

I tried two types of dataBuffer, one is from malloc(), another one is from mmap().

And I use strace to watch what the kernel will do on these two kind of buffer. Most of them are the same, but I saw when doing write(), they look different.

buffer from malloc()

[pid   258] open("/mnt/mtd/mmc/block/DATA10", O_WRONLY|O_CREAT, 0644) = 3
[pid   258] write(3, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"..., 691200) = 691200

buffer from mmap()

[pid   262] open("/mnt/mtd/mmc/block/DATA10", O_WRONLY|O_CREAT, 0644) = 4
[pid   262] write(4, 0x76557000, 691200) = 691200

Like you can see above, the parameters of write() are different, one is "FFFFF..." like I memset before, but another is like a memory address.

Also the first parameter is different, one is 3, another is 4.

And on my system, buffer from malloc() is faster than mmap().

How come they are different? Who made this different?

Thanks.

Update: how do I measure malloc() is faster?

I trace deep inside the write() in kernel, find out the last step of write() is iov_iter_copy_from_user_atomic(), I think this is the actual memory copy operation.

Then I using gettimeofday() to measure how long the iov_iter_copy_from_user_atomic() cost in malloc/mmap buffer.

1
How did you measure malloc() being faster?Frank Meerkötter
@FrankMeerkötter I update how I measure the timeEason
Isn't there an strace option that will show timestamps so you can see the time taken by system calls?Barmar
@Barmar yes, there is ,but in the beginning, I didn't plan to use strace to see the time cost, I already find the mmap() is slower, then I try to use strace to find out why it slow.Eason
Use your strace output to check which syscall is actually used by malloc to do the allocation.Krzysztof Adamski

1 Answers

-1
votes

I think it's checking whether there's a trailing 0 byte at the end of the buffer. If there is, it assumes the data is a string and displays it with quotes. If not, it just shows the address.

I can't think of a reason why the buffer from malloc() would be faster than mmap(). Calling memset() should get the memory of both into RAM, so the write() shouldn't have to wait for anything to be loaded into memory.