BitcoinTalk
Auto-detect for 128-bit 4-way SSE2

View Satoshi only

External link

SVN rev 150 has some code to try to auto-detect whether to use 4-way SSE2.  We need this because it's only faster on certain newer CPUs that have 128-bit SSE2 and not ones with 64-bit SSE2.

It uses the CPUID instruction to get the CPU brand, family, model number and stepping.  That's the easy part.  Knowing what to do with the model number is the hard part.  I was not able to find any table of family, model and stepping numbers for CPUs.  I had to go by various random reports I saw.

Here's what I ended up with:
Code:
 // We need Intel Nehalem or AMD K10 or better for 128bit SSE2
  // Nehalem = i3/i5/i7 and some Xeon
  // K10 = Opterons with 4 or more cores, Phenom, Phenom II, Athlon II
  //  Intel Core i5  family 6, model 26 or 30
  //  Intel Core i7  family 6, model 26 or 30
  //  Intel Core i3  family 6, model 37
  //  AMD Phenom    family 16, model 10
  bool fUseSSE2 = ((fIntel && nFamily * 10000 + nModel >=  60026) ||
                   (fAMD   && nFamily * 10000 + nModel >= 160010));

I saw some sporadic inconsistent model numbers for AMD CPUs, so I'm not sure if this will catch all capable AMDs.

If it's wrong, you can still override it with -4way or -4way=0.

It prints what it finds in debug.log.  Search on CPUID.

This is only enabled if built with GCC.
You should benchmark all implementations (using cpu time, not realtime) and choose the fastest and while benchmarking check whether the algorithm actually works.
You should benchmark all implementations (using cpu time, not realtime) and choose the fastest and while benchmarking check whether the algorithm actually works.

Yeah, while implementing the cuda hasher I thought about this. There should be an interface to the hashing handler (or even a full miner per implementation) and we should have a simple way of giving it a known block, ask it to hash 1000 nonces and compare the result, while benchmarking at the same time. Shouldn't be too hard to implement and would help when developing new algorithms.

The interface schema would also help if we were to plug in an fpga based engine or something of the kind, having specific entry points into the code without having to tweak on the default mining schema.
You should benchmark all implementations (using cpu time, not realtime) and choose the fastest and while benchmarking check whether the algorithm actually works.

+1 agreed.  It's not difficult or time-consuming for each user to do this at startup.

Since the function CallCPUID function contains x86 assembler, it breaks the build on other architectures. I've changed line 2770 in main.cpp to

#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)

to make it compile again, at least on ARM.
I wonder if we could get the VIA C7 code included with an autodetect in the standard clients? Or is this just too rare a beast to trouble the main code over? The C7 does work with the standard clients with regular pentium or sse2 code albeit slower.

> There should be an interface to the hashing handler (or even a full miner per implementation)

+1. In case someone wants FPGA/whatever specific accelerator he has.
Since the function CallCPUID function contains x86 assembler, it breaks the build on other architectures. I've changed line 2770 in main.cpp to

#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)

to make it compile again, at least on ARM.
Added in SVN rev 152