Mkfile(8) is severely syscall limited on OS X
blog.metaobject.com
blog.metaobject.com
Actually, no. Irrespective of mkfile being mostly MacOSX specific, most sycalls on MacOSX are just plain slow as compared to Linux (or FreeBSD). I think this is partially an artifact of performance not being a major metric for most system calls on MacOSX. The systems calls where performance is a critical metric (like timekeeping) use a kernel / user shared page interface to avoid the syscall entirely in the vast majority of the cases.
I recall doing benchmarking roughly 10 years ago to find the best interface to communicate with a mostly in an OS-bypass HPC driver. MacOSX ioctls were some multipler more expensive than Linux, but the native IOKit Mach IPC was even more expensive than that. Sigh. There was a similar story for sockets in non-OS bypass mode, where simply writing on a socket was far more expensive than Linux.
Somebody needs to resurrect lmbench & do a comparison of the various x86 kernels available these days. Maybe that would shame Apple into focusing on performance.
Drew
2GB/s is pretty damn fast, 0.5 nanoseconds per byte.
dd if=./big_file.file of=/dev/null bs=64K
535020540 bytes (535 MB, 510 MiB) copied, 8.70128 s, 61.5 MB/s
dd if=./big_file.file of=/dev/null bs=4K
535020540 bytes (535 MB, 510 MiB) copied, 8.36283 s, 64.0 MB/s
dd if=./big_file.file of=/dev/null bs=1K
535020540 bytes (535 MB, 510 MiB) copied, 8.82508 s, 60.6 MB/s
Only thing gone up is the cpu usage (same is negligible at ~60MB/s).
dd if=/dev/zero of=/dev/null bs=1K count=1024K
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.06113 s, 1.0 GB/s
dd if=/dev/zero of=/dev/null bs=4K count=256K
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.343595 s, 3.1 GB/s
dd if=/dev/zero of=/dev/null bs=32K count=32K
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.160191 s, 6.7 GB/s
This becomes a bigger issue if it's not a kernel-based, local FS, but something that does more work, I mentioned FUSE above. Since no read merging happens, small reads like 4k or 32k start to hurt earlier, especially if the FS is written in an interpreter. Some of these also mishandled small reads, incurring an additional penalty (I know because I fixed that in an implementation).
Even the fastest SSD is not even near the speed of /dev/zero. Easy to extrapolate any speed from those two points (minus the filesystem overhead (the thing we are talking about is the block layer)).
I'd be interested in a test of a FUSE based fs like ntfs. So if you have one, just run some tests. (don't forget to flush the cache)
https://github.com/coreutils/coreutils/blob/master/src/ioblk...
"It's not what you don't know that kills you. It is what you know for sure that ain't true" -- Mark Twain
dd is designed to copy raw block data across devices.
Sure, you can abuse both for either purpose, but seems rather misguided to call it out explicitly. What did you intend to gain by doing it?
dd is also designed to copy data from one file to another, in blocks, with optional conversion of the data (eg, from EBCDIC to ASCII), and with optional offsets/limits to copy regions of a file.
dd is not designed to copy raw block data, it is merely a different file copy tool.
dd is for transform-and-copy, so you're abusing dd when writing disk ISOs. The fact that most of the Internet is wrong doesn't make you any less wrong.
"dd is not a disk writing tool" http://www.vidarholen.net/contents/blog/?p=479
'In the above example it can be seen that an input block size of 128K is optimal for my particular setup.'
However, the SSD seems to be significantly slower, so the relative overhead of the syscall is going to be respectively less:
'Reading from /dev/zero and writing out to a SSD with a more optimal block size of 256K yields a throughput of 280 MB/s.'
I was getting 250MB/s with the 512 byte buffer size, although the test in the article is doing two syscalls (one read(), one write()) whereas mkfile is just doing one.
At 256KB buffer size I was already getting around 1.8GB/second writing to SSD.
Actually, in this article, Linux writing to RAM is slower than MacOS writing to SSD. Hard to conclude that "it's just OS X being slow". I suspect the hardware used is wildly different from the one in the original article.
Specifically, do the syscalls writing the file go through multiple protection domains?
https://maniagnosis.crsr.net/2011/07/this-is-comment-i-made-...
Apple worked on MkLinux, but it isn't technically a predecessor to Mac OS X. The two do not share a single line of code; if they did, Apple would have to license Mac OS under the GPL.
XNU, the Mac OS kernel (https://en.wikipedia.org/wiki/XNU) isn't a real microkernel; the functionality of a microkernel is there, but quite a bit of code was added that, in a true microkernel, would live in userspace.
What is a good sweet spot that runs well on older hardware (less then 10 years old) and new hardware? And should network buffers be bigger or smaller then disk buffers?
Disk IO buffers, it's easy nowadays, just use something like a MB, which is just fine for almost any application, and doesn't stack up to much memory use (unless you're writing many files concurrently, which can bring it's own problems as well)
Are syscalls more expensive on OSX?
mkfile is not available on Linux. The equivalent utility is xfs_mkfile or fallocate.
xfs_mkfile could do what mkfile does, the description isn't conclusive enough.
dd if=/dev/zero of=test bs=1k seek=2m count=1
Or python: python -c 'f=open("test", "w"); f.seek(2e9); f.write("\x00")'
Both these calls create a ~2GB file with holes in it. They return almost instantly on OSX.EDIT: oh wait, this isn't what you want. you want a file _without_ holes, my mistake.
dd if=/dev/zero of=test bs=1k count=2mmacOS supports sparse bundle with HFS+
Then, experiment with various buffer sizes (bs=1k, 10k, 100k, 1M) - I personally use 1M with dd.
Be warned on OS X you have to use /dev/rdiskX instead of /dev/diskX, as the latter is a buffered version that usually is slower.
so
dd if=/dev/zero of=foo bs=1k count=1m
would write 1GB in 1k blocks, and dd if=/dev/zero of=foo bs=1m count=1k
would write 1GB in 1m blocks.Then you're at the whim of more or less obscure caching layers in the Linux kernel. At least there's a filesystem cache plus something in the block-device layer that reads ahead in order to speed up fread calls with low buffer sizes.
Also, due to filesystem fragmentation the file will be distributed across locations on the disk - that doesn't matter much for SSDs, but on "spinning rust" the head seeks distort the performance. A dd on a raw disk, however, will not cause any seeks except those for background processes' file operations.
I've read that some Linux distributions have `mkfile', but it's just a script wrapper around `dd'.
But yes, syscalls are more expensive on OSX.
[1]: http://stackoverflow.com/questions/26796729/quickly-create-a...
Can you elaborate on this?
The XNU implements system calls in the same way a BSD system does. If you are talking about the Mach aspect of OS X, the BSD part can call down to the the Mach directly without using Mach messages. XNU is not a traditional microkernel even though Mach is in there.
[1]: http://sekhon.berkeley.edu/macosx/
[2]: http://www.academia.edu/2685902/An_Analysis_of_Mac_OS_X_Leop...
I have spent a great deal of time studying the code path taken on system calls in xnu/osfmk[3] versus Linux[4] in building my Linux emulator for OSX[5].
[3]: https://opensource.apple.com/source/xnu/xnu-1504.3.12/osfmk/...
[4]: https://github.com/torvalds/linux/blob/master/arch/x86/entry...
[5]: https://github.com/geocar/ml/
I think many OSX supporters do the platform a disservice by defending it without spending any time studying it or the competition. OSX has some serious performance-based weaknesses, that are perhaps a real worthwhile trade for a lot of things "just working" -- especially when compared to Windows or Linux -- but are still a weakness.
I was more responding to the blanket statement that system calls are more expensive on OS X.
You first citation is ancient by the way, thats 11 years ago now.
You second link states in the conclusion section:
"First, Mac OSX uses a hybrid monolithic and microkernel architecture inwhich system calls must be wrapped into an RPC messageto the Mach microkernel. "
But in XNU/Darwin there are three different mechanism for systems calls - traditional BSD style traps, Mach traps, and Mach RPC.
I didn't really understand how the other 3 links related or I guess specifically what I was looking for in those.
Not to imply that it is "hidden" but I am curious if any HN users know about this and understand its purpose?
The upshot is that it looks like it constructs some non-env variable environment data on the program's stack after the posix environment.
The absolute path of the executable, followed by preemption free zone addresses, entropy, a configuration setting for malloc allocation strategy, and the address of the main thread's stack afaict.
dd of=/dev/zero of=/ddtest.out myfile bs=64k count=65536
> X-Axis is buffer size in KB. The original 512 byte size isn't on there because it would be 0.5KB or the entire axis would need to be bytes, which would also be awkward at the larger sizes. Also note that the X-Axis is logarithmic.
-n Create an empty filename. The size is noted, but disk blocks aren't allocated until data is written to them
Also the description on the man file says: mkfile creates one or more files that are suitable for use as NFS-mounted swap areas. The sticky bit is set, and the file is padded with zeroes by default