I finally found some time to check what the GPLv3 is about (10 years after it was released). I knew that it is trying to solve some problems with web services and plug into them viral component of GPL but I never understood it. I put together what it is all about so hopefully my summary will help to somebody to decide what licence to use.
There exists something called ASP Loophole. Which I understood like this:
Situation 1
You develop amazing desktop application
You use GPLv2 to develop your application
You distribute binaries of your application to clients
Because you used GPLv2 to develop your desktop you have to publish your app with GPL compatible licence and when distributing it to client you must make source code of your app available
Situation 2
You develop some very useful web service (e.g. google search)
You use GPLv2 to develop your web service
You publish your web service to the internet and start charge clients for using it
Because you never ever publish binaries of your web service you don’t have to ever publish source code of your application
The new GPLv3 is something what tries to prevent Situation 2 and says that you must publish source code even in such situation. The question is if this is good or bad.
Imagine you work in any of the thousands enterprises of the world, lets say some international bank. You create web service, internet banking or anything else for your client. If you touch GPLv3 in your enterprise, whatever you develop and make available via web service to the world, must be made available with source code. Happy persuading your managers and legal department etc. that they should let you use open source. I would call this shooting into your own leg
Another question is how would GPLv3 solve situation of micro services? Because in that case I don’t develop web service published to service. I create multiple web services with GPLv3. In the end I have one API service which does nothing else just calls other web service, doesn’t reference any GPLv3 code directly and we’re in the same situation as with GPLv2. Or have I missed something?
I’m fan of Solarized palette so I wanted to find way how to get it to Console2 which I was made to use at my working PC. There is just 16 basic colours in Solarized palette so it should be easy to use them in console. The problem started the moment when I realised there is no obvious mapping between base terminal colours and Solarized palette. Most of the examples is for source code editors as Vim and specific language which pretty controlled environment. We know what combinations of colours are used so we can build the theme. If we want to bring it to console where each different application or command can do whatever mixture of colours they want, we have much harder work.
I’m .NET developer, so my main use-case is readable msbuild output, but the target is to have any coloured output as close as possible to base terminal colours (or at least to maintain readability).
Just for reference this is how the base terminal colours look (not actual msbuild output, just compilation of different msbuild output lines to see all the possible used colour combinations):
And one more for Powershell fans, the default theme used by it:
So I went to the google to search for few options and I found couple of Console 2 themse on GitHub but none particularly compelling. They either contained errors or were not readable much due to bad combination of colours.
Then I discovered that Conemu uses Solarized palette in one of its themes, it is nicely readable and pretty close to base terminal colours. I created version of it for Console 2 and put it to GitHub for everybody interested:
After comparing it to Solarized palette used in some applications I realised that although it maps base terminal colours to Solarized colours as closely as possible, there is problem with using background and content colours. Most of the terminals uses colour 7 as default content colour. The Conemu uses actually background colour in its place. So although it is perfectly readable the contrast is not in accordance to original Solarized idea. After bit of experimenting I created one more version which I put to GitHub as well and I try to use it for some time. Maybe somebody finds it even more useful:
I tried to use the background and base content colours which Solarized suggests (colours at index 7 and 15). I had to move the two brightest colours somewhere, so I decided to put them on index 2 and 3 which are not often used and if they will be used it will still be readable. In my case of msbuild, I had bad luck because colour 4 is used but most of the console usage should be fine.
New version of .NET Framework 4.6 with a lot of new features in it was release few weeks ago. One feature which got my attention is support for Simple Instruction Multiple Data (SIMD) vector instructions in the new 64-bit JIT compiler named RyuJIT. I wanted to see how easy is it to leverage this SIMD support and what performance improvements we can expect for code using it.
Introduction to SIMD
The SIMD types of instructions are as the name suggests instructions which take multiple operands and do some vector type operation with it (e.g. adding two vectors). They can work with different types (e.g. int, float, double, etc.) and the level of parallelism (vector size) depends on length of the register.
There are two types of vector instructions available in x86 compatible processors. The older one came with SSE2 instruction set which contains 128 bit registers for vector operations. The newer instructions are available in different type of AVX instruction sets. Depending on instruction set supported on processor (AVX, AVX2, AVX-512) it has register with size up to 512 bit. RyuJIT is trying to use the best one available for the CPU on which it is going to execute the code.
The support for SIMD was added just to the new RyuJIT compiler which at this moment works just for x64 programs. There were some claims that RyuJIT can be extended to other platforms as well but for now there will be no improvement for x86 programs. Second thing worth mentioning is that although the .NET team has target to run code using SIMD wrapper classes on the par with sequential code in case SIMD cannot be used, there are no there yet.
The way in which RyuJIT and .NET Framework adds support for SMID is by attaching JitIntristicAttribute to class or method. JIT then knows that it can ignore normal bytecode of the method and it can replace it with some special handling (e.g. SIMD instruction). There are few classes which are marked with JitIntristicAttribute so they should use SIMD optimisation (with proper JIT support):
Vector2 – Fixed vector of two floating point numbers (e.g. to represent point in 2D space)
Vector3 – Fixed vector of three floating point numbers (e.g. to represent point in 3D space)
Vector4 – Fixed vector of four floating point numbers
Vector<T> – Variable length vector of type T (128 bit – 256 bit depending on supported instruction set)
The first there fixed vector length types are part of BCL in .NET Framework 4.6 in System.Numerics namespace. The variable length vector type is available as NuGet package System.Numerics.Vectors version 4.1.0. For .NET Framework 4.5 both fixed and variable length type are in the same NuGet package of version 4.0.0.
Performance test
I created simple test which is multiplying two vectors in loop. The result amount of operations equals approximately to multiplying two matrices of size 100k x 100k. There are more complicated elaborate available but since I wanted to compare how the same code runs on different platforms and versions of .NET Framework I used just this simple test.
The test I created is trying to use all currently supported vector classes plus scalar implementation of vector multiplication as benchmark. I compiled the code in both .NET Framework 4.5.2 and in 4.6 and in both platforms x86 and x64. I ran the tests on laptop with Intel Core i7-2640M and on desktop with Intel Core i7-3770. Both of them have support for SSE-2 and AVX (which have 128 bit registers).
I don’t have access to any CPU which has support for AVX2 (256 bit) or AVX-512 (512 bit) unfortunately. If somebody has CPU which supports this instruction sets, let me know results of running the test application. I’d like to know the results for them as well. The source code for the application which I used is available on GitHub (taynes13/SimdTest).
The following table contains the test results. I did average of five test runs in order to avoid some random fluctuations. I normalised results for every CPU in order to be able to compare them, the value 100% is for x64 running on .NET Framework 4.6.
.NET Version
Platform
Method
Avg. Time
Perf. Imp.
i7-2640M
i7-3770
i7-2640M
i7-3770
.NET 4.6
x64
Scalar
00:09.3
00:08.2
100.00%
100.00%
.NET 4.6
x86
Scalar
00:09.4
00:08.2
98.90%
100.16%
.NET 4.5.2
x64
Scalar
00:09.5
00:08.3
97.35%
99.44%
.NET 4.5.2
x86
Scalar
00:09.3
00:08.2
100.00%
100.35%
.NET 4.6
x64
VectorT
00:05.6
00:03.5
167.02%
237.01%
.NET 4.6
x86
VectorT
01:11.7
01:02.6
12.94%
13.16%
.NET 4.6
x64
Vector2
00:23.0
00:15.2
40.43%
54.10%
.NET 4.6
x86
Vector2
00:21.5
00:17.7
43.18%
46.56%
.NET 4.5.2
x64
Vector2
00:23.3
00:15.1
39.89%
54.40%
.NET 4.5.2
x86
Vector2
00:21.2
00:17.7
43.79%
46.52%
.NET 4.6
x64
Vector3
00:19.4
00:13.8
47.90%
59.83%
.NET 4.6
x86
Vector3
00:20.0
00:16.9
46.31%
48.72%
.NET 4.5.2
x64
Vector3
00:19.4
00:13.9
47.93%
59.15%
.NET 4.5.2
x86
Vector3
00:20.4
00:17.8
45.59%
46.27%
.NET 4.6
x64
Vector4
00:17.6
00:13.1
52.88%
62.66%
.NET 4.6
x86
Vector4
00:25.9
00:23.3
35.88%
35.34%
.NET 4.5.2
x64
Vector4
00:17.7
00:13.1
52.48%
62.86%
.NET 4.5.2
x86
Vector4
00:26.0
00:23.5
35.74%
35.00%
Performance improvements of using Vector classes in different .NET Framework configurations
There are few interesting observations
The Vector<T> running on the new RyuJIT (x64 .NET 4.6) with SIMD support has increased performance of multiplication by almost 2.5x on the desktop CPU (and bit more moderate improvement by 1.7x for laptop CPU).
The same Vector<T> running on x86 .NET 4.6 was running 7.5x slower than scalar multiplication and almost 18x slower than the x64 RyuJIT using SIMD.
All the other Vector2, Vector3 and Vector4 classes had very similar performance on both .NET 4.5.2 and .NET 4.6
There was no performance improvement for x64 RyuJIT compiled code for Vector2, Vector3 and Vector4 classes. The actually performance degradation, for all the vector types the code runs on average 2x slower than scalar implementation
Summary
In my tests I can see that it is beneficial to use Vector<T> type if and only if we can ensure the application is going to run on x64 bit .NET Framework 4.6. If we are not sure whether the program is going to run on x86 or x64, it is better to avoid using Vector<T> because it will be by almost order of magnitude slower on x86 than scalar implementation. As I mentioned earlier the .NET team has target to run the programs using Vector classes without performance hit if run on x86 but we will have to wait for it.
Second thing which surprised me in my tests is that I haven’t seen performance improvements for any of the fixed length vectors (compared to x86 or event .NET Framework 4.5.2). This suggests that SIMD is disabled for the Vector classes in BCL of .NET Framework 4.6. I have seen everywhere on internet articles how RyuJIT adds support for SIMD but nothing about this support being switched off for fixed Vector classes. If somebody has some explanation, let me know, please.
To summarise my tests in one sentence, the support for RyuJIT is definitely promising, but one has to be careful where and how is the code going to be compiled and run (at least for now).