On Feb 15, 2017, at 4:40 AM, Darren Duncan <[email protected]> wrote:
>
> On 2017-02-15 2:40 AM, Clemens Ladisch wrote:
>> Cecil Westerhof wrote:
>>
>> And just like with assembly code, you also have to count the time spent
>> writing it, and debugging the result.
>
> Also, its a long time since hand-writing assembly code was any good for
> performance, unless you're a 1% top expert with a good reason.
While true insofar as it goes, that attitude leads to people being ignorant of
what the compiler produces from the code you give it. This almost caused a
threading bug in a program I was modifying recently, and we only caught it
ahead of time because someone questioned some basic assumptions, causing me to
go look at the generated assembly.
Consider this humble lone line of code:
++i;
The threading bug is right there, staring at you.
What, you don’t see it? How about now:
https://godbolt.org/g/xfJ9SQ
Yeah, that’s right, friends, integer increment isn’t a single instruction on
ARM, even with gcc -O2, hence it is not atomic! It takes at least three
instructions (load, modify, store) and for some reason GCC chose to use 6 in
this particular case. (Probably some remnant of the function calling
convention.)
That means that if you’re depending on that increment to be atomic across
threads, you’re going to be in for a shock of the old bank balance transaction
problem form. (You know, the one every SQL newbie gets taught, where the
account gets double-debited or double-credited if you don’t use transactions.)
The solution is to use GCC’s atomic increment primitive — also shown via the
above link for comparison — which adds a couple of “dmb” ARM instructions to
lock the code to a single CPU core through that critical section.
A software developer who refuses to learn about his processor’s assembly
language is like trying to become an electrical engineer without learning
anything about physics. A typical practicing EE won’t need to break out
Maxwell’s equations every day, but understanding the implications of those
equations is what separates engineering from tinkering.
> If you want speed, write in C or something else that isn't assembly. The
> odds are like 99% that the modern C compiler will generate faster code than
> you could ever write yourself in assembly, and it will be much less buggy.
Just to be sure people understand my position here, I will agree with this
again.
If you don’t like my example above as presented, consider also that it supports
the “threads are evil” hypothesis. If you can’t count on a simple preincrement
to be atomic, what else are you misunderstanding about what’s going on at the
low levels of the system when it runs your multithreaded program?
(And no, it wasn’t my idea to use threads in the program I was modifying in the
first place! One of the planned upcoming changes is to redesign it from a
2-thread system to two cooperating single-threaded programs communicating over
an IPC channel.)
> Similarly with threads, for the vast majority of people, using other
> concurrency models with supported languages are better; they will still get
> the performance benefit of using multiple CPU cores but do it much more
> safely than if you are explicitly using "threads" in code.
Also agreed. I recommend starting with message-passing, and move on to other
methods only when you can prove that won’t give the required benefit.
I also recommend that you go learn you some Erlang (for great good):
http://learnyousomeerlang.com/content
If you can’t get past the syntax, you can paper over it with the Ruby-like
Elixir front-end:
http://elixir-lang.org/
But to bring all of this back around on topic, beware that a SQL DB is
basically a global variable store, albeit with arbitrated access. You can
create cross-process problems by misuse of the data store just as you can with
global variables in a traditional threaded program.
Message-passing concurrency is just a tool that increases your chances of
effortless success, it is not a guarantee of it. No system that allows side
effects can guarantee proper ordering of operations without some thought given
to it, whether the mechanisms involved are mutexes, transactions, or something
else.
Concurrency is hard.
_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users