Skip to contentSkip to conversation

Update LZO compression

GIT PULL Markus F.X.J. Oberhumer 8 participants 20 messages Aug 13, 2012 – Sep 7, 2012 Btrfs file system

lore
Share & tools
lore
#0 lore raw

Hi all,

as suggested on the mailing list I have converted the updated LZO code into git, so please pull my "lzo-update" branch from

git://github.com/markus-oberhumer/linux.git lzo-update

You can browse the branch at

https://github.com/markus-oberhumer/linux/compare/lzo-update

I'd ask some official kernel maintainer for review and to push this into linux-next so that it will hopefully land in the 3.7 release.

Share and enjoy,
Markus

Quoted 20 lines · Markus F.X.J. Oberhumer

Hi all,

I finally have prepared a small package that updates the LZO version in the Linux kernel. Please get it from:

http://www.oberhumer.com/opensource/lzo/download/Testing/linux-kernel-lzo-20120716.tar.gz

As stated in the README this version is significantly faster (typically more than 2 times faster!) than the current version, has been thoroughly tested on x86_64/i386/powerpc platforms and is intended to get included into the official Linux 3.6 or 3.7 release.

I encourage all compression users to test and benchmark this new version, and I also would ask some official LZO maintainer to convert the updated source files into a GIT commit and possibly push it to Linus or linux-next.

Share and enjoy,
Markus

Signature · 1 line
Markus Oberhumer, <[email protected]>, http://www.oberhumer.com/
#1 lore raw
Quoted 10 lines · Markus F.X.J. Oberhumer

Hi all,

as suggested on the mailing list I have converted the updated LZO code into git, so please pull my "lzo-update" branch from

git://github.com/markus-oberhumer/linux.git lzo-update

You can browse the branch at

https://github.com/markus-oberhumer/linux/compare/lzo-update

Looks ok to me from a quick look.

Since kernel lzo is security relevant, I assume the new version has been fuzz tested?

I couldn't tell from the github view, but I assume you follow standard coding style.

-Andi

#2 lore raw
Quoted 8 lines · Andi Kleen
Quoted 7 lines · Markus F.X.J. Oberhumer

Hi all,

as suggested on the mailing list I have converted the updated LZO code into git, so please pull my "lzo-update" branch from

git://github.com/markus-oberhumer/linux.git lzo-update

Quoted 8 lines
Quoted 3 lines

You can browse the branch at

https://github.com/markus-oberhumer/linux/compare/lzo-update

Looks ok to me from a quick look.

Since kernel lzo is security relevant, I assume the new version has been fuzz tested?

Of course!

Quoted 2 lines

I couldn't tell from the github view, but I assume you follow standard coding style.

I've tried my best to follow the style guidelines.

Cheers,
Markus

Quoted 3 lines

-Andi

Signature · 1 line
Markus Oberhumer, <[email protected]>, http://www.oberhumer.com/
#3 lore raw
In reply to Markus F.X.J. Oberhumer
Quoted 10 lines · Markus F.X.J. Oberhumer
Quoted 9 lines · Markus F.X.J. Oberhumer

As stated in the README this version is significantly faster (typically more than 2 times faster!) than the current version, has been thoroughly tested on x86_64/i386/powerpc platforms and is intended to get included into the official Linux 3.6 or 3.7 release.

I encourage all compression users to test and benchmark this new version, and I also would ask some official LZO maintainer to convert the updated source files into a GIT commit and possibly push it to Linus or linux-next.

Sorry for not reporting earlier, but I didn't have time to do real benchmarks, just a quick test on ARM926EJ-S using barebox, and found in the new version decompression is slower:
http://lists.infradead.org/pipermail/barebox/2012-July/008268.html

BTW, do you have userspace code matching the old and new lzo versions? It would be easier to benchmark.

Unfortunately I cannot claim high confidence in my benchmark results due to missing time to do it properly, it would be useful if someone else could do some benchmarks on ARM before merging this.

Johannes

#4 lore raw

Hi Johannes,

Quoted 8 lines · Johannes Stezenbach
Quoted 7 lines · Markus F.X.J. Oberhumer
Quoted 6 lines · Markus F.X.J. Oberhumer

As stated in the README this version is significantly faster (typically more than 2 times faster!) than the current version, has been thoroughly tested on x86_64/i386/powerpc platforms and is intended to get included into the official Linux 3.6 or 3.7 release.

Quoted 8 lines
Quoted 3 lines
Quoted 3 lines

I encourage all compression users to test and benchmark this new version, and I also would ask some official LZO maintainer to convert the updated source files into a GIT commit and possibly push it to Linus or linux-next.

Sorry for not reporting earlier, but I didn't have time to do real benchmarks, just a quick test on ARM926EJ-S using barebox, and found in the new version decompression is slower:
http://lists.infradead.org/pipermail/barebox/2012-July/008268.html

I can only guess, but maybe your ARM cpu does not have an efficient implementation of {get,put}_unaligned().

Could you please try the following patch and test if you can see any significant speed difference?

Thanks,
Markus

lib/lzo/lzodefs.h +7 -0
index ddc8db5..efc5714 100644
@@ -12,8 +12,15 @@
  */
 
 
+#if defined(__arm__)
+#define COPY4(dst, src)        \
+               (dst)[0] = (src)[0]; (dst)[1] = (src)[1]; \
+               (dst)[2] = (src)[2]; (dst)[3] = (src)[3]
+#endif
+#ifndef COPY4
 #define COPY4(dst, src)        \
                put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
+#endif
 #if defined(__x86_64__)
 #define COPY8(dst, src)        \
                put_unaligned(get_unaligned((const u64 *)(src)), (u64 *)(dst))
Quoted 10 lines

BTW, do you have userspace code matching the old and new lzo versions? It would be easier to benchmark.

Unfortunately I cannot claim high confidence in my benchmark results due to missing time to do it properly, it would be useful if someone else could do some benchmarks on ARM before merging this.

Johannes

Signature · 1 line
Markus Oberhumer, <[email protected]>, http://www.oberhumer.com/
#5 lore raw

Hi Marcus,

Quoted 13 lines · Markus F.X.J. Oberhumer
Quoted 12 lines · Johannes Stezenbach
Quoted 10 lines · Markus F.X.J. Oberhumer
Quoted 9 lines · Markus F.X.J. Oberhumer

As stated in the README this version is significantly faster (typically more than 2 times faster!) than the current version, has been thoroughly tested on x86_64/i386/powerpc platforms and is intended to get included into the official Linux 3.6 or 3.7 release.

I encourage all compression users to test and benchmark this new version, and I also would ask some official LZO maintainer to convert the updated source files into a GIT commit and possibly push it to Linus or linux-next.

Quoted 7 lines
Quoted 4 lines

Sorry for not reporting earlier, but I didn't have time to do real benchmarks, just a quick test on ARM926EJ-S using barebox, and found in the new version decompression is slower:
http://lists.infradead.org/pipermail/barebox/2012-July/008268.html

I can only guess, but maybe your ARM cpu does not have an efficient implementation of {get,put}_unaligned().

Yes, ARMv5 cannot do unaligned access. ARMv6+ could, but I think the Linux kernel normally traps it for debug, all ARM seem to use generic {get,put}_unaligned() implementation which use byte access and shift.

Quoted 2 lines

Could you please try the following patch and test if you can see any significant speed difference?

It isn't. I made the attached quick hack userspace code
using ARM kernel headers and barebox unlzop code.
(new == your new code, old == linux-3.5 git, test == new + your suggested change) (sorry I had no time to clean it up)

I compressed a Linux Image with lzop (lzop <arch/arm/boot/Image >lzoimage) and timed uncompression:

# time ./unlzopold <lzoimage >/dev/null
real    0m 0.29s
user    0m 0.19s
sys     0m 0.10s
# time ./unlzopold <lzoimage >/dev/null
real    0m 0.29s
user    0m 0.20s
sys     0m 0.09s
# time ./unlzopnew <lzoimage >/dev/null
real    0m 0.41s
user    0m 0.30s
sys     0m 0.10s
# time ./unlzopnew <lzoimage >/dev/null
real    0m 0.40s
user    0m 0.30s
sys     0m 0.10s
# time ./unlzopnew <lzoimage >/dev/null
real    0m 0.40s
user    0m 0.29s
sys     0m 0.11s
# time ./unlzoptest <lzoimage >/dev/null
real    0m 0.39s
user    0m 0.28s
sys     0m 0.11s
# time ./unlzoptest <lzoimage >/dev/null
real    0m 0.39s
user    0m 0.27s
sys     0m 0.11s
# time ./unlzoptest <lzoimage >/dev/null
real    0m 0.39s
user    0m 0.27s
sys     0m 0.11s

FWIW I also checked the sha1sum to confirm the Image uncompressed OK.

Johannes
-------------- next part --------------
A non-text attachment was scrubbed...
Name: lzo-bench.tar.gz
Type: application/octet-stream
Size: 54224 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120815/85539467/attachment-0001.obj>

#6 lore raw
Quoted 19 lines · Johannes Stezenbach
Quoted 18 lines · Markus F.X.J. Oberhumer
Quoted 16 lines · Johannes Stezenbach
Quoted 10 lines · Markus F.X.J. Oberhumer
Quoted 9 lines · Markus F.X.J. Oberhumer

As stated in the README this version is significantly faster (typically more than 2 times faster!) than the current version, has been thoroughly tested on x86_64/i386/powerpc platforms and is intended to get included into the official Linux 3.6 or 3.7 release.

I encourage all compression users to test and benchmark this new version, and I also would ask some official LZO maintainer to convert the updated source files into a GIT commit and possibly push it to Linus or linux-next.

Sorry for not reporting earlier, but I didn't have time to do real benchmarks, just a quick test on ARM926EJ-S using barebox, and found in the new version decompression is slower:
http://lists.infradead.org/pipermail/barebox/2012-July/008268.html

Quoted 7 lines
Quoted 2 lines

I can only guess, but maybe your ARM cpu does not have an efficient implementation of {get,put}_unaligned().

Yes, ARMv5 cannot do unaligned access. ARMv6+ could, but I think the Linux kernel normally traps it for debug, all ARM seem to use generic {get,put}_unaligned() implementation which use byte access and shift.

Hmm - I could imagine that we're wasting a lot of possible speed gain by not exploiting that feature on ARMv6+.

Quoted 7 lines
Quoted 2 lines

Could you please try the following patch and test if you can see any significant speed difference?

It isn't. I made the attached quick hack userspace code
using ARM kernel headers and barebox unlzop code.
(new == your new code, old == linux-3.5 git, test == new + your suggested change) (sorry I had no time to clean it up)

My suggested COPY4 replacement probably has a lot of load stalls - maybe some ARM expert could have a look and suggest a more efficient implementation.

In any case, I still would like to see the new code in linux-next because of the huge improvements on other modern CPUs.

Cheers,
Markus

Quoted 41 lines

I compressed a Linux Image with lzop (lzop <arch/arm/boot/Image >lzoimage) and timed uncompression:

# time ./unlzopold <lzoimage >/dev/null
real    0m 0.29s
user    0m 0.19s
sys     0m 0.10s
# time ./unlzopold <lzoimage >/dev/null
real    0m 0.29s
user    0m 0.20s
sys     0m 0.09s
# time ./unlzopnew <lzoimage >/dev/null
real    0m 0.41s
user    0m 0.30s
sys     0m 0.10s
# time ./unlzopnew <lzoimage >/dev/null
real    0m 0.40s
user    0m 0.30s
sys     0m 0.10s
# time ./unlzopnew <lzoimage >/dev/null
real    0m 0.40s
user    0m 0.29s
sys     0m 0.11s
# time ./unlzoptest <lzoimage >/dev/null
real    0m 0.39s
user    0m 0.28s
sys     0m 0.11s
# time ./unlzoptest <lzoimage >/dev/null
real    0m 0.39s
user    0m 0.27s
sys     0m 0.11s
# time ./unlzoptest <lzoimage >/dev/null
real    0m 0.39s
user    0m 0.27s
sys     0m 0.11s

FWIW I also checked the sha1sum to confirm the Image uncompressed OK.

Johannes

Signature · 1 line
Markus Oberhumer, <[email protected]>, http://www.oberhumer.com/
#7 lore raw
Quoted 7 lines · Markus F.X.J. Oberhumer
Quoted 5 lines · Johannes Stezenbach

I made the attached quick hack userspace code
using ARM kernel headers and barebox unlzop code.
(new == your new code, old == linux-3.5 git, test == new + your suggested change) (sorry I had no time to clean it up)

Quoted 5 lines

My suggested COPY4 replacement probably has a lot of load stalls - maybe some ARM expert could have a look and suggest a more efficient implementation.

In any case, I still would like to see the new code in linux-next because of the huge improvements on other modern CPUs.

Well, ~2x speedup on x86 is certainly a good achievement, but there are more ARM based devices than there are PCs, and I guess many embedded devices use lzo compressed kernels and file systems while I'm not convinced many PCs rely on lzo in the kernel.

I know everyone's either busy or on vacation, but it would be so cool if someone could test on a more modern ARM core, with the userspace test code I posted it should be easy to do.

Johannes

#8 lore raw
Quoted 4 lines · On Thu, 16 Aug 2012 17:06:47 +0200 Johannes Stezenbach <[email protected]> wrote:

Well, ~2x speedup on x86 is certainly a good achievement, but there are more ARM based devices than there are PCs, and I guess many embedded devices use lzo compressed kernels and file systems while I'm not convinced many PCs rely on lzo in the kernel.

Keep in mind that a major user of LZO is the BTRFS filesystem, and I believe it is used much more often on larger machines than on ARM, in fact it had problems operating on ARM at all, until quite recently.

Quoted 3 lines

I know everyone's either busy or on vacation, but it would be so cool if someone could test on a more modern ARM core, with the userspace test code I posted it should be easy to do.

I have locked the Allwinner A10 CPU in my Mele A2000 to 60 MHz using cpufreq-set, and ran your test. rnd.lzo is a 9 MB file from /dev/urandom compressed with lzo. There doesn't seem to be a significant difference between all three variants.

# time for i in {1..20}; do old/unlzop < rnd.lzo >/dev/null ; done

real 0m11.353s
user 0m3.060s
sys 0m8.170s

# time for i in {1..20}; do new/unlzop < rnd.lzo >/dev/null ; done

real 0m11.416s
user 0m3.030s
sys 0m8.200s

# time for i in {1..20}; do test/unlzop < rnd.lzo >/dev/null ; done

real 0m11.310s
user 0m3.100s
sys 0m8.150s

Signature · 15 lines
With respect,
Roman

~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Stallman had a printer,
with code he could not see.
So he began to tinker,
and set the software free."
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120816/d1a5e749/attachment.sig>
#9 lore raw
Quoted 3 lines

I have locked the Allwinner A10 CPU in my Mele A2000 to 60 MHz using cpufreq-set, and ran your test. rnd.lzo is a 9 MB file from /dev/urandom compressed with lzo. There doesn't seem to be a significant difference between all three variants.

I found that in compression benchmarks it depends a lot on the data compressed.

urandom (which should be essentially incompressible) will be handled by different code paths in the compressor than other more compressible data. It becomes a complicated memcpy then.

But then there are IO benchmarks which also only do zeroes, which also gives an unrealistic picture.

Usually it's best to use some corpus with different data types, from very compressible to less so; and look at the aggregate.

For my snappy work I usually had at least large executables (medium) and some pdfs (already compressed; low) and then uncompressed source code tars (high compression)

-Andi

#10 lore raw
Quoted 10 lines · Andi Kleen
Quoted 3 lines

I have locked the Allwinner A10 CPU in my Mele A2000 to 60 MHz using cpufreq-set, and ran your test. rnd.lzo is a 9 MB file from /dev/urandom compressed with lzo. There doesn't seem to be a significant difference between all three variants.

I found that in compression benchmarks it depends a lot on the data compressed.

urandom (which should be essentially incompressible) will be handled by different code paths in the compressor than other more compressible data. It becomes a complicated memcpy then.

In addition, locking the CPU to 60 MHz may improve the memory access penalty, as a cache miss may cost much less cycles.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#11 lore raw

looks like ARM results are inconclusive from a lot of folks without bandwidth to do a write-up, what about just plain STAGING status for ARM so the android tweakers can beat on it for a while?

Quoted 8 lines · Geert Uytterhoeven
Quoted 1 line · Andi Kleen
Quoted 1 line

I have locked the Allwinner A10 CPU in my Mele A2000 to 60 MHz using

cpufreq-set,

Quoted 1 line
Quoted 1 line

and ran your test. rnd.lzo is a 9 MB file from /dev/urandom compressed

with lzo.

Quoted 1 line
Quoted 1 line

There doesn't seem to be a significant difference between all three

variants.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120816/b717da79/attachment-0001.html>

#12 lore raw
Quoted 3 lines · james northrup

looks like ARM results are inconclusive from a lot of folks without bandwidth to do a write-up, what about just plain STAGING status for ARM so the android tweakers can beat on it for a while?

Staging only really works for new drivers, not for updating existing library functions like this.

I suppose you could keep both and have the architecture select with a CONFIG.

-Andi

#13 lore raw
Quoted 11 lines · Andi Kleen
Quoted 3 lines · james northrup

looks like ARM results are inconclusive from a lot of folks without bandwidth to do a write-up, what about just plain STAGING status for ARM so the android tweakers can beat on it for a while?

Staging only really works for new drivers, not for updating existing library functions like this.

I suppose you could keep both and have the architecture select with a CONFIG.

I've been doing some rough benchmarking with the updated LZO in btrfs.

My tests primarily consist of timing some typical copying, git manipulating, and running rsync using a set of kernel git sources. Git sources are typically about 50% pack files which won't compress very well, with the remainder being mostly highly compressible source files.

Of course, any underlying speed improvement attributable only to LZO is not shown by test like this. But I thought it would be interesting to see the impact in some typical real-world btrfs operations.

I was seeing between 3-9% improvement in speed with the new LZO.

Copying several directories of git sources showed the most improvement, ~9%. Typical git operations, such as a git checkout or git status where only showing 3-5% improvement, which is close to the noise level of my tests. Running multiple rsync processes showed a 5% improvement.

With only 10 trials (5 with each LZO), I can't say I would statistically hang my hat on these numbers.

Given all the other stuff that is going on in my rough benchmarks, a 3-9% improvement from a single change is probably pretty good.

#14 lore raw
In reply to james northrup
Quoted 3 lines · james northrup

looks like ARM results are inconclusive from a lot of folks without bandwidth to do a write-up, what about just plain STAGING status for ARM so the android tweakers can beat on it for a while? ?

Again staging doesn't really work for a core library, it's more for separate drivers.

FWIW we did some tests and the new library seems to be generally faster on x86.

-Andi

Signature · 1 line
ak at linux.intel.com -- Speaking for myself only
#15 lore raw
In reply to Geert Uytterhoeven

looks like ARM results are inconclusive, what about just plain STAGING status for arm to let the android tweakers beat on it for a while? they're full of bandwidth for the last mile performance observations

Quoted 1 line
Quoted 1 line
Quoted 1 line

There doesn't seem to be a significant difference between all three variants.

#16 lore raw
In reply to Markus F.X.J. Oberhumer
Quoted 23 lines · Markus F.X.J. Oberhumer
Quoted 22 lines · Johannes Stezenbach
Quoted 20 lines · Markus F.X.J. Oberhumer
Quoted 8 lines · Johannes Stezenbach
Quoted 7 lines · Markus F.X.J. Oberhumer
Quoted 6 lines · Markus F.X.J. Oberhumer

As stated in the README this version is significantly faster (typically more than 2 times faster!) than the current version, has been thoroughly tested on x86_64/i386/powerpc platforms and is intended to get included into the official Linux 3.6 or 3.7 release.

Quoted 8 lines
Quoted 3 lines
Quoted 3 lines

I encourage all compression users to test and benchmark this new version, and I also would ask some official LZO maintainer to convert the updated source files into a GIT commit and possibly push it to Linus or linux-next.

Sorry for not reporting earlier, but I didn't have time to do real benchmarks, just a quick test on ARM926EJ-S using barebox, and found in the new version decompression is slower:
http://lists.infradead.org/pipermail/barebox/2012-July/008268.html

I can only guess, but maybe your ARM cpu does not have an efficient implementation of {get,put}_unaligned().

Quoted 7 lines
Quoted 4 lines

Yes, ARMv5 cannot do unaligned access. ARMv6+ could, but I think the Linux kernel normally traps it for debug, all ARM seem to use generic {get,put}_unaligned() implementation which use byte access and shift.

Hmm - I could imagine that we're wasting a lot of possible speed gain by not exploiting that feature on ARMv6+.

Or you could just realize that unaligned accesses are slow in the best case, and are simply not supported on some processors.

If you think a little bit, I bet you could come up with a solution that operates at cacheline-aligned granularity, something that would be _even faster_ than simply fixing the code to do aligned accesses.

Jeff

#17 lore raw
Quoted 3 lines

If you think a little bit, I bet you could come up with a solution that operates at cacheline-aligned granularity, something that would be _even faster_ than simply fixing the code to do aligned accesses.

Cache aligned compression is unlikely to compress anything at all. Compression algorithms are usually by definition unaligned.

-Andi

#18 lore raw
Quoted 6 lines · Andi Kleen
Quoted 3 lines

If you think a little bit, I bet you could come up with a solution that operates at cacheline-aligned granularity, something that would be _even faster_ than simply fixing the code to do aligned accesses.

Cache aligned compression is unlikely to compress anything at all. Compression algorithms are usually by definition unaligned.

Sure it's a bitstream, but that does not imply the impossibility of reading data in in an word-aligned manner.

Maybe cache-aligned is ambitious, because of resultant code bloat, but machine-int-aligned is doable and reasonable.

Jeff

#19 lore raw
Quoted 5 lines · Jeff Garzik
Quoted 4 lines · Andi Kleen
Quoted 3 lines

If you think a little bit, I bet you could come up with a solution that operates at cacheline-aligned granularity, something that would be _even faster_ than simply fixing the code to do aligned accesses.

Quoted 8 lines
Quoted 2 lines

Cache aligned compression is unlikely to compress anything at all. Compression algorithms are usually by definition unaligned.

Sure it's a bitstream, but that does not imply the impossibility of reading data in in an word-aligned manner.

Maybe cache-aligned is ambitious, because of resultant code bloat, but machine-int-aligned is doable and reasonable.

Well, I for one would be content if the old and new lzo versions could be merged based on CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS.

(Assuming that the slowdown on ARM is due to unaligned access, since the old version also uses get/put_unaligned, is the new version actually using more unaligned accesses?)

Johannes