skeeto / enchive

Encrypted personal archives
The Unlicense
632 stars 51 forks source link

execution speed on openbsd 7.3 #31

Open bK4gYuRo opened 1 year ago

bK4gYuRo commented 1 year ago

enchive on openbsd 7.3 runs ~5 times slower than on macos 10.13 or void linux.

Extraction of the same archive file takes 11.5 sec on openbsd and less than 2 seconds on macos:

On openbsd:

$ time ./enchive -s ~/.keep/keep.s extract < ~/.keep/.keep.enc > /dev/null passphrase: 0m18.62s real 0m11.46s user 0m00.10s system

On macos:

$ time ./enchive -s ~/.keep/keep.s extract < ~/.keep/.keep.enc > /dev/null passphrase:

real 0m7.87s user 0m1.59s sys 0m0.02s

Could the slowdown be caused by openbsd libc?

bK4gYuRo commented 1 year ago

A few more details:

openbsd runs on this hardware: hw.model=Intel(R) Celeron(R) CPU N3160 @ 1.60GHz

macos hardware is this:

Intel(R) Core(TM) i7-2677M CPU @ 1.80GHz

skeeto commented 1 year ago

The only libc functions that might have an effect in this case is fread and fwrite. Enchive uses typical buffered streams, and I do not expect OpenBSD would do anything that would make these measurably slower.

I remembered OpenBSD had been using an ancient fork of GCC, but they've since adopted Clang, and a recent LLVM (13.0.0) at that. So it's not caused by an old compiler. They use unusual -fno-builtin options by default, but "cc -v" doesn't list anything that matters for Enchive.

Next I installed OpenBSD in QEMU to run tests, and found two differences of note. First, reading files on OpenBSD is sloooow. (Is there no page cache?) It's adding about 50% to the total run time. My setup:

$ dd if=/dev/zero of=zero bs=1M count=512 $ enchive -pp -ss k

Then this:

$ enchive -pp -ss a /dev/null

Is about 50% slower than this:

$ dd if=/dev/zero bs=1M count=512 | enchive -pp -ss a >/dev/null

On a Debian 11 VM, which I also ran in the same QEMU configuration on the same host to make it a fair test, there's no difference if the input is warmed up. That's exactly what I would expect from Linux.

Extra: Try replacing Enchive with "cat" in the above to observe file versus pipe performance directly. I hadn't expected such a difference!

Second, even without reading from the file system, it was still more than 2x slower than my Debian VM. Next I "pkg_add gcc" to install GCC 11.2 and compiled with "egcc":

$ make clean $ make CC=egcc

With piped input it's equally as fast as my Debian VM. This confirms OpenBSD libc is not the issue. With file input, it's about 2x slower, due to the slower file system. It seems using a non-base GCC instead of the base Clang makes a substantial difference.

When I build with Debian 11's Clang 11.0.1, it's about 15% slower than its GCC 10.2. That's about in range for typical compiler differences. A >200% difference is not. OpenBSD has done something to their base toolchain that causes it produce significantly slower binaries. That's not too surprising because they often trade away performance for other (perceived) gains, e.g. disabling hyper-threading.

I'm not personally interested in spending time figuring out what exactly in their Clang configuration is causing the slowdown. Perhaps an extra compiler option or two can it turn off. I expect the typical OpenBSD user is fine with this performance hit in exchange for the theoretical security benefits it's supposed to provide.

bK4gYuRo commented 1 year ago

Thank you for the research and explanation! For my personal use I am going to compile it with gcc. I will bring up clang issue on openbsd mailing list.