Live data from Hacker News

How the JVM compares strings on x86 using pcmpestri

jcdav.is

61–70 of 73 posts

Re: How the JVM compares strings on x86 using pcmpestri

#61
post #40

The JVM has a number of cool features that enable you to efficiently drop down into C (FFI) yourself: these tricks aren't just for built-ins. A quick overview: - First there was JNI. JNI means that you write method stubs with the "native" keyword. Then you run javah, which gives you some C glue code that you eventually need to compile. This is very fast, but it's annoying because now you need a tool chain everywhere.…

There is a project to get something like JNR bundled with the JDK – see http://openjdk.java.net/jeps/191 and http://openjdk.java.net/projects/panama/

Re: How the JVM compares strings on x86 using pcmpestri

#62
post #40

The JVM has a number of cool features that enable you to efficiently drop down into C (FFI) yourself: these tricks aren't just for built-ins. A quick overview: - First there was JNI. JNI means that you write method stubs with the "native" keyword. Then you run javah, which gives you some C glue code that you eventually need to compile. This is very fast, but it's annoying because now you need a tool chain everywhere.…

JNR (and JNA and cffi) strike me as unsafe due to the lack of type enforcement. Systems like this let you call any random pointer as if it were a C function of any type. That usually works, but sometimes doesn't. If you're lucky, mistakes make your program blow up right away. If you're unlucky, you get impossible to diagnose memory corruption. I'd much rather write conventional bridges and have the system check that…

The solution is to have some tool which parses C header files and uses them to build the Java bindings.

Unfortunately, C is a pretty nasty language to parse, so you end up using something like http://www.swig.org/ or https://github.com/rpav/c2ffi to parse it for you. But the challenge with adopting those sort of tools for Java is they aren't written in Java, they are written in C and/or C++. (Obviously that doesn't stop you from using them with Java, but it does make the whole thing less pleasant.)

Re: How the JVM compares strings on x86 using pcmpestri

#63
post #40

The JVM has a number of cool features that enable you to efficiently drop down into C (FFI) yourself: these tricks aren't just for built-ins. A quick overview: - First there was JNI. JNI means that you write method stubs with the "native" keyword. Then you run javah, which gives you some C glue code that you eventually need to compile. This is very fast, but it's annoying because now you need a tool chain everywhere.…

If folks are interested in this, I figured some folks might like our c++ version of this (been around for 5 years ish now): https://github.com/bytedeco/javacpp

Also comes with tons of pre cooked projects already ready to go: https://github.com/bytedeco/javacpp-presets

We use it in production at skymind and it powers our whole cpu and gpu stack with built in memory management among other things.

Also has maven and sbt plugins so you can plug it right in to your workflow automatically just maintaining the java code.

One of the coolest features is the name matching so you can get semi automatic mapping.

We auto generate our JNI bindings from this.

Re: How the JVM compares strings on x86 using pcmpestri

#65

I find it a bit sad that, instead of optimising the existing REP CMPS instruction to do vectorised compares like they did with REP MOVS/STOS and block copies/writes, Intel introduced another even more complex instruction that itself requires a bunch of additional support code to use. I certainly don't think it's a "good use of CISC".

pcmpxstrx is a lot more powerful than rep cmps. I'm lukewarm on pcmpxstrx too, but for a different reason: I'd prefer the effort to go into more general purpose, highly flexible SIMD instructions (which is thankfully happening now with AVX 512).

What do you think about Cray-style vectors, which are coming back in the form of ARM SVE and the RISC-V V extension?

At least the latter claims code compiled once is compatible with all possible hardware configurations, from the start (by way of giving the CPU a "remaining iterations count" and having it reply with how many it can do for the chosen vector lane shapes).

IMO, if it does end up working that well in practice, it does put all of the various incompatible versions of packed SIMD extensions in a pretty awkward spot - could we have skipped all of MMX, SSE, AVX, NEON, etc. versions with technology that has been around for almost half a century?

Re: How the JVM compares strings on x86 using pcmpestri

#66

It's great to see the disassembly. Would be curious to see the assembly performance-tested against other similar implementations (UTF-16 compatible.) Btw, frik, you are shadow banned. I sense it is for the frigid opinions. Personally, I see them as "ok" as long as you provide technical reasons for your opinions and are polite enough.

It has nothing to do with "frigid opinions"; we banned the account for egregious serial abuse of the site.

Please don't do such digressions in HN comments. If you don't think a user should be banned, you're welcome to email us. And of course you can vouch for their good comments.

Re: How the JVM compares strings on x86 using pcmpestri

#67
post #48

Earlier quoted context omitted.

Even in 2017, not everyone is a Web or Electron developer. I certainly am not. I don’t advocate using UTF16 for the web, but people still code native desktop apps, mobile apps, embedded software, videogames, store stuff in various databases, etc. For such use, markup is irrelevant.

Even outside Web, you still have mostly-ASCII: * filenames * identifiers * config files * text protocols * host names, email addresses * embedded scripts (including SQL and OpenGL shaders) * command line interfaces * translations for languages using Latin alphabets I don't think 2/3 size reduction for some languages will offset the cost in all the other places.

If English is your world yeah.

Some of us use other languages and like to use them everywhere we can.

Re: How the JVM compares strings on x86 using pcmpestri

#68
post #23

Earlier quoted context omitted.

That's path dependence [0]. When all of those were conceived in the nineties, 2-byte UCS-2 seemed to be enough to store all unicode code points. UTF-16 came only later, once it was clear 65535 code points is too few. Had those languages been designed in last 10 years, all of them would pick UTF-8 as their code point format. [0]: https://en.wikipedia.org/wiki/Path_dependence

Some JavaScript runtimes (Firefox's Spidermonkey for one) have an optimization that stores some strings in single-byte format where possible to mitigate the cost of the awful original choice to use UCS-2 for JS strings. I expect some other runtimes do this too, but I don't know any off-hand. IIRC this was motivated by Firefox OS (strings eat up a lot of RAM on memory-starved $50 smartphones) but it pays off on deskto…

Python as of 3.3 uses any of three different internal storage mechanisms for strings: 1-byte (latin-1), 2-byte (UCS-2) or 4-byte (UCS-4) depending on the width of the highest code point in the string. This allows the internal storage to always be fixed-width, while still saving space for strings which contain, say, only code points representable in a single byte.

Prior to 3.3, the internal storage of Unicode was determined by a flag during compilation of the interpreter; a "narrow" compiled interpreter would use 2-byte strings with surrogate pairs for non-BMP code points, and a "wide" compiled interpreter would use 4-byte strings.

Re: How the JVM compares strings on x86 using pcmpestri

#69
post #32
post #22

Earlier quoted context omitted.

Are you telling us it's not a secret then?

Don’t know if this is sarcasm, but no, doubtful it’s a secret. Or might depend on the JVM license. OpenJDK obviously has no secrets. But otherwise, assembly overrides for hot paths in execution targets that support them aren’t actually a big secret, just that they’re rarely visible. Think Go has a lot of processed architecture specific assembly for some functions, especially crypto iirc.

Yeah, it was a sarcasm. The article (quoted in parent comment) called it a secret implementation.

Re: How the JVM compares strings on x86 using pcmpestri

#70
post #48

Earlier quoted context omitted.

Even in 2017, not everyone is a Web or Electron developer. I certainly am not. I don’t advocate using UTF16 for the web, but people still code native desktop apps, mobile apps, embedded software, videogames, store stuff in various databases, etc. For such use, markup is irrelevant.

Even outside Web, you still have mostly-ASCII: * filenames * identifiers * config files * text protocols * host names, email addresses * embedded scripts (including SQL and OpenGL shaders) * command line interfaces * translations for languages using Latin alphabets I don't think 2/3 size reduction for some languages will offset the cost in all the other places.

For some of these things we don’t have much choice, because the encoding is part of some lower-level API (file system, OpenGL, CLI), which usually don’t accept arbitrary encoding. They accept only one, and unless you want to waste time converting, you better use that exact encoding.

Other stuff like IDs, shaders before GL 4.2, and many text protocols aren’t Unicode at all.

For configs I usually use UTF-8 myself, because I don’t like writing parsers for custom formats and just use XML, and any standard-compliant parser supports all of them.

Post reply on HN