Skip to content

Commit 69585d9

Browse files
authored
Merge pull request #70 from centaurean/dev
Add MSVC support and continuous integration
2 parents 235ebe9 + d621db1 commit 69585d9

28 files changed

+270
-192
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ script:
1313
- tar zxvf premake.tar.gz
1414
- ./premake5 gmake
1515
- make
16-
- ./bin/release/benchmark -f
16+
- ./bin/Release/benchmark -f

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
0.14.1
2+
------
3+
*January 20, 2018*
4+
- Added MSVC support
5+
- Added continuous integration on travis and appveyor
6+
- Premake script improvement
7+
- Various codebase improvements
8+
19
0.14.0
210
------
311
*January 16, 2018*

README.md

Lines changed: 66 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
DENSITY
1+
DENSITY
22
========
33
Superfast compression library
44

@@ -8,6 +8,11 @@ It is focused on high-speed compression, at the best ratio possible. **All three
88

99
DENSITY features a simple API to enable quick integration in any project.
1010

11+
Branch|Linux & OSX|Windows
12+
--- | --- | ---
13+
master|[![Build Status](https://travis-ci.org/centaurean/density.svg?branch=master)](https://travis-ci.org/centaurean/density)|[![Build status](https://ci.appveyor.com/api/projects/status/rf7x3x829il72cii/branch/master?svg=true)](https://ci.appveyor.com/project/gpnuma/density/branch/master)
14+
dev|[![Build Status](https://travis-ci.org/centaurean/density.svg?branch=dev)](https://travis-ci.org/centaurean/density)|[![Build status](https://ci.appveyor.com/api/projects/status/rf7x3x829il72cii/branch/dev?svg=true)](https://ci.appveyor.com/project/gpnuma/density/branch/dev)
15+
1116
Why is it so fast ?
1217
-------------------
1318

@@ -68,64 +73,99 @@ Build
6873
-----
6974
DENSITY can be built on a number of platforms. It uses the [premake](http://premake.github.io/) build system.
7075

71-
It was developed and optimized against Clang/LLVM, but GCC is also supported (please use a recent version for maximum performance).
72-
At this time MSVC is *not* supported, but it's straightforward to install clang for windows.
73-
74-
The following assumes you already have *git* installed.
76+
It was developed and optimized against Clang/LLVM which makes it the preferred compiler, but GCC and MSVC are also supported. Please use the latest compiler versions for best performance.
7577

7678
**Mac OS X**
7779

7880
On OS X, Clang/LLVM is the default compiler, which makes things simpler.
7981

80-
1) Download and install [premake5](http://premake.github.io/) for OS X and make it available in your path.
82+
1) First things first, install the [homebrew package manager](https://brew.sh/).
83+
84+
2) Then the prerequisites from the command line :
85+
86+
```
87+
brew install git wget
88+
```
89+
90+
3) Now the source code, and premake :
91+
92+
```
93+
git clone https://github.com/centaurean/density.git
94+
cd density/build
95+
wget https://github.com/premake/premake-core/releases/download/v5.0.0-alpha12/premake-5.0.0-alpha12-macosx.tar.gz -O premake.tar.gz
96+
tar zxvf premake.tar.gz
97+
```
8198

82-
2) Run the following from the command line :
99+
5) Finally, build and test :
83100

84101
```
85-
cd build
86-
premake5 gmake
102+
./premake5 gmake
87103
make
104+
bin/Release/benchmark -f
88105
```
89106

90107
**Linux**
91108

92-
On Linux, Clang/LLVM is not always available by default.
109+
On Linux, Clang/LLVM is not always available by default, but can be easily added thanks to the provided package managers.
110+
The following example assumes a Debian or Ubuntu distribution with *apt-get*.
93111

94-
1) Install Clang/LLVM *(optional if GCC is installed)* if you don't have it already (on Debian distributions for example, *sudo apt-get install clang* should do the trick)
112+
1) From the command line, install Clang/LLVM (*optional*, GCC is also supported if Clang/LLVM can't be used) and other prerequisites.
95113

96-
2) Download and install [premake5](http://premake.github.io/) for Linux and make it available in your path.
114+
```
115+
sudo apt-get install clang git wget
116+
```
97117

98-
3) Run the following from the command line :
118+
2) Get the source code and premake :
99119

100120
```
101-
cd build
102-
premake5 gmake
121+
git clone https://github.com/centaurean/density.git
122+
cd density/build
123+
wget https://github.com/premake/premake-core/releases/download/v5.0.0-alpha12/premake-5.0.0-alpha12-linux.tar.gz -O premake.tar.gz
124+
tar zxvf premake.tar.gz
125+
```
126+
127+
3) And finally, build and test :
128+
129+
```
130+
./premake5 gmake
103131
make
132+
bin/Release/benchmark -f
104133
```
105134

106135
**Windows**
107136

108-
On Windows, things are a (little) bit more complicated.
137+
On Windows, things are (slightly) more complicated. We'll use the [chocolatey package manager](https://chocolatey.org/) for simplicity.
109138

110-
1) First, check if you have git installed, if not you can [get it here](https://www.git-scm.com/download/win). Make it available in your path.
139+
1) Please install [chocolatey](https://chocolatey.org/install).
111140

112-
2) We'll use *GNU make* to build the project, on Windows it's not part of the default toolset but you can [download a port here](http://gnuwin32.sourceforge.net/packages/make.htm). Make it available in your path.
141+
2) From the command line, get the prerequisites :
113142

114-
3) Microsoft Visual Studio is required as we will use its linker, [get it here](https://www.visualstudio.com/en-us/products/free-developer-offers-vs.aspx).
143+
```
144+
choco install git wget unzip
145+
```
115146

116-
4) Now we can install Clang/LLVM for Windows, and thanks to the **ClangOnWin** project it's easy ! You can [download it here](http://sourceforge.net/projects/clangonwin/). Make it available in your path.
147+
3) Install the [Visual Studio IDE community edition](https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community) if you don't already have it.
117148

118-
5) Download and install [premake5](http://premake.github.io/) for Windows and make it available in your path (edit the Path environment variable).
149+
4) Download and install [Clang/LLVM for Windows](http://releases.llvm.org/5.0.1/LLVM-5.0.1-win64.exe) (*optional*, MSVC compiler is also supported but resulting binaries might be slower).
119150

120-
6) Run the following from the command line :
151+
5) Open a [developer command prompt](https://docs.microsoft.com/en-us/dotnet/framework/tools/developer-command-prompt-for-vs) and type :
121152

122153
```
123-
cd build
124-
premake5.exe gmake
125-
make
154+
git clone https://github.com/centaurean/density.git
155+
cd density/build
156+
wget https://github.com/premake/premake-core/releases/download/v5.0.0-alpha12/premake-5.0.0-alpha12-windows.zip -O premake.zip
157+
unzip premake.zip
158+
```
159+
160+
6) Build and test :
161+
162+
```
163+
premake5.exe vs2017
164+
msbuild Density.sln
165+
bin\Release\benchmark.exe -f
126166
```
127167

128-
And that's it ! You can now use the integrated in-memory benchmark to test your files (the *benchmark* or *benchmark.exe* binary in the build/bin/Release/ folder).
168+
And that's it ! If you open the Visual Studio IDE, in the solutions explorer by right-clicking on project names you can change platform toolsets, if you also want to try other compilers.
129169

130170
Output format
131171
-------------

appveyor.yml

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
1-
version: 0.14.0.{build}
1+
version: 0.14.1.{build}
22
image: Visual Studio 2015
33
init:
44
- cmd:
55
install:
66
- cmd: >-
7-
set PATH=C:\Program Files\7-Zip;C:\ProgramData\chocolatey\bin;C:\Program Files\Git\cmd;C:\Program Files\Git\usr\bin;C:\projects\density\build\mingw64\bin\
8-
9-
choco install wget
7+
choco install wget unzip
108
119
cd build
1210
1311
wget https://github.com/premake/premake-core/releases/download/v5.0.0-alpha12/premake-5.0.0-alpha12-windows.zip -nv -O premake5.zip
1412
15-
7z x premake5.zip
13+
unzip premake5.zip
1614
1715
del premake5.zip
18-
19-
wget https://qa.debian.org/watch/sf.php/mingw-w64/x86_64-7.2.0-release-posix-seh-rt_v5-rev1.7z -nv --no-check-certificate -O mingw.7z
20-
21-
7z x mingw.7z
22-
23-
del mingw.7z
2416
build_script:
2517
- cmd: >-
26-
premake5.exe gmake
18+
premake5.exe vs2015
2719
28-
mingw32-make.exe CC=gcc.exe
20+
msbuild.exe Density.sln
2921
test_script:
3022
- cmd: bin\Release\benchmark.exe -f

benchmark/src/benchmark.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ int main(int argc, char *argv[]) {
125125
uint8_t value = (uint8_t) rand();
126126
for (unsigned int count = 0; count < uncompressed_size; count++) {
127127
if (!(rand() & 0xf))
128-
value += rand();
128+
value += (uint8_t)rand();
129129
in[count] = value;
130130
}
131131
out = malloc(memory_allocated * sizeof(uint8_t));
@@ -229,11 +229,11 @@ int main(int argc, char *argv[]) {
229229
double total_compress_time = 0.0;
230230
double total_decompress_time = 0.0;
231231
double total_time = 0.0;
232-
double decompress_speed;
233-
double decompress_speed_low;
234-
double decompress_speed_high;
235-
double compress_time_elapsed;
236-
double decompress_time_elapsed;
232+
double decompress_speed = 0.0;
233+
double decompress_speed_low = 0.0;
234+
double decompress_speed_high = 0.0;
235+
double compress_time_elapsed = 0.0;
236+
double decompress_time_elapsed = 0.0;
237237
cputime_chronometer chrono;
238238

239239
while (total_time <= 10.0) {
@@ -285,7 +285,7 @@ int main(int argc, char *argv[]) {
285285
printf("<=> ");
286286
DENSITY_BENCHMARK_BLUE(printf("Decompress speed ");
287287
DENSITY_BENCHMARK_BOLD(printf("%.0lf MB/s", decompress_speed)));
288-
printf(" (min %.0lf MB/s, max %.0lf MB/s, best %.4lfs) ", decompress_speed_low, decompress_speed_high, decompress_time_low);
288+
printf(" (min %.0lf MB/s, max %.0lf MB/s, best %.4lfs) ", decompress_speed_low, decompress_speed_high, decompress_time_low);
289289
}
290290
fflush(stdout);
291291
}

benchmark/src/benchmark.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@
5454
#define DENSITY_BENCHMARK_COMPILER_VERSION __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__
5555
#elif defined(_MSC_VER)
5656
#define DENSITY_BENCHMARK_COMPILER "MSVC"
57-
#define DENSITY_BENCHMARK_COMPILER_VERSION
57+
#define DENSITY_BENCHMARK_COMPILER_VERSION ""
5858
#elif defined(__INTEL_COMPILER)
5959
#define DENSITY_BENCHMARK_COMPILER "ICC"
60-
#define DENSITY_BENCHMARK_COMPILER_VERSION
60+
#define DENSITY_BENCHMARK_COMPILER_VERSION ""
6161
#else
6262
#define DENSITY_BENCHMARK_COMPILER "an unknown compiler"
63-
#define DENSITY_BENCHMARK_COMPILER_VERSION
63+
#define DENSITY_BENCHMARK_COMPILER_VERSION ""
6464
#endif
6565

6666
#if defined(_WIN64) || defined(_WIN32)

build/premake5.lua

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,19 @@
3535
--
3636

3737
-- Check for tools
38-
if os.execute("clang -v") == true then
38+
if package.config:sub(1,1) == "\\" then
39+
if os.execute("clang -v") == true then
40+
toolset "msc-llvm-vs2014"
41+
else
42+
io.write("INFO : Selected compiler is MSVC. You might get better performance with Clang/LLVM.\n")
43+
end
44+
elseif os.execute("clang -v") == true then
3945
toolset "clang"
4046
elseif os.execute("gcc -v") == true then
4147
toolset "gcc"
48+
io.write("INFO : Selected compiler is GCC. You might get better performance with Clang/LLVM.\n")
4249
else
43-
io.write("No supported compiler found on the command line. Please install Clang/LLVM or GCC.\n")
50+
io.write("ERROR : No supported compiler found on the command line. Please install Clang/LLVM, GCC, or MSC.\n")
4451
os.exit(0)
4552
end
4653

@@ -53,11 +60,14 @@ end
5360
os.execute("git submodule update --init --recursive")
5461

5562
solution "Density"
56-
configurations { "release" }
63+
configurations { "Release" }
5764
flags { "NoFramePointer", "LinkTimeOptimization" }
5865
optimize "Speed"
5966
cdialect "C99"
6067
warnings "Extra"
68+
if os.is64bit() then
69+
architecture "x64"
70+
end
6171

6272
project "density"
6373
kind "SharedLib"

src/algorithms/algorithms.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
#include "algorithms.h"
3636

37-
DENSITY_WINDOWS_EXPORT DENSITY_FORCE_INLINE void density_algorithms_prepare_state(density_algorithm_state *const restrict state, void *const restrict dictionary) {
37+
DENSITY_WINDOWS_EXPORT DENSITY_FORCE_INLINE void density_algorithms_prepare_state(density_algorithm_state *const DENSITY_RESTRICT state, void *const DENSITY_RESTRICT dictionary) {
3838
state->dictionary = dictionary;
3939
state->copy_penalty = 0;
4040
state->copy_penalty_start = 1;

src/algorithms/algorithms.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ typedef struct {
6666
state->copy_penalty_start >>= 1;
6767

6868
#define DENSITY_ALGORITHM_TEST_INCOMPRESSIBILITY(span, work_block_size)\
69-
if (density_unlikely(span & ~(work_block_size - 1))) {\
69+
if (DENSITY_UNLIKELY(span & ~(work_block_size - 1))) {\
7070
if (state->previous_incompressible)\
7171
state->copy_penalty = state->copy_penalty_start;\
7272
state->previous_incompressible = true;\
7373
} else\
7474
state->previous_incompressible = false;
7575

76-
DENSITY_WINDOWS_EXPORT void density_algorithms_prepare_state(density_algorithm_state *const, void *const);
76+
DENSITY_WINDOWS_EXPORT void density_algorithms_prepare_state(density_algorithm_state *const DENSITY_RESTRICT_DECLARE, void *const DENSITY_RESTRICT_DECLARE);
7777

7878
#endif

src/algorithms/chameleon/core/chameleon_decode.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,17 @@
4444

4545
#include "chameleon_decode.h"
4646

47-
DENSITY_FORCE_INLINE void density_chameleon_decode_process_compressed(const uint16_t hash, uint8_t **restrict out, density_chameleon_dictionary *const restrict dictionary) {
47+
DENSITY_FORCE_INLINE void density_chameleon_decode_process_compressed(const uint16_t hash, uint8_t **DENSITY_RESTRICT out, density_chameleon_dictionary *const DENSITY_RESTRICT dictionary) {
4848
DENSITY_MEMCPY(*out, &dictionary->entries[hash].as_uint32_t, sizeof(uint32_t));
4949
}
5050

51-
DENSITY_FORCE_INLINE void density_chameleon_decode_process_uncompressed(const uint32_t chunk, uint8_t **restrict out, density_chameleon_dictionary *const restrict dictionary) {
51+
DENSITY_FORCE_INLINE void density_chameleon_decode_process_uncompressed(const uint32_t chunk, uint8_t **DENSITY_RESTRICT out, density_chameleon_dictionary *const DENSITY_RESTRICT dictionary) {
5252
const uint16_t hash = DENSITY_CHAMELEON_HASH_ALGORITHM(chunk);
5353
(&dictionary->entries[hash])->as_uint32_t = chunk;
5454
DENSITY_MEMCPY(*out, &chunk, sizeof(uint32_t));
5555
}
5656

57-
DENSITY_FORCE_INLINE void density_chameleon_decode_kernel(const uint8_t **restrict in, uint8_t **restrict out, const density_bool compressed, density_chameleon_dictionary *const restrict dictionary) {
57+
DENSITY_FORCE_INLINE void density_chameleon_decode_kernel(const uint8_t **DENSITY_RESTRICT in, uint8_t **DENSITY_RESTRICT out, const density_bool compressed, density_chameleon_dictionary *const DENSITY_RESTRICT dictionary) {
5858
if (compressed) {
5959
uint16_t hash;
6060
DENSITY_MEMCPY(&hash, *in, sizeof(uint16_t));
@@ -73,11 +73,11 @@ DENSITY_FORCE_INLINE bool density_chameleon_decode_test_compressed(const uint_fa
7373
return (density_bool const) ((signature >> shift) & DENSITY_CHAMELEON_SIGNATURE_FLAG_MAP);
7474
}
7575

76-
DENSITY_FORCE_INLINE void density_chameleon_decode_4(const uint8_t **restrict in, uint8_t **restrict out, const uint_fast64_t signature, const uint_fast8_t shift, density_chameleon_dictionary *const restrict dictionary) {
76+
DENSITY_FORCE_INLINE void density_chameleon_decode_4(const uint8_t **DENSITY_RESTRICT in, uint8_t **DENSITY_RESTRICT out, const uint_fast64_t signature, const uint_fast8_t shift, density_chameleon_dictionary *const DENSITY_RESTRICT dictionary) {
7777
density_chameleon_decode_kernel(in, out, density_chameleon_decode_test_compressed(signature, shift), dictionary);
7878
}
7979

80-
DENSITY_FORCE_INLINE void density_chameleon_decode_256(const uint8_t **restrict in, uint8_t **restrict out, const uint_fast64_t signature, density_chameleon_dictionary *const restrict dictionary) {
80+
DENSITY_FORCE_INLINE void density_chameleon_decode_256(const uint8_t **DENSITY_RESTRICT in, uint8_t **DENSITY_RESTRICT out, const uint_fast64_t signature, density_chameleon_dictionary *const DENSITY_RESTRICT dictionary) {
8181
uint_fast8_t count = 0;
8282

8383
#ifdef __clang__
@@ -91,12 +91,12 @@ DENSITY_FORCE_INLINE void density_chameleon_decode_256(const uint8_t **restrict
9191
#endif
9292
}
9393

94-
DENSITY_FORCE_INLINE void density_chameleon_decode_read_signature(const uint8_t **restrict in, density_chameleon_signature *restrict signature) {
94+
DENSITY_FORCE_INLINE void density_chameleon_decode_read_signature(const uint8_t **DENSITY_RESTRICT in, density_chameleon_signature *DENSITY_RESTRICT signature) {
9595
DENSITY_MEMCPY(signature, *in, sizeof(density_chameleon_signature));
9696
*in += sizeof(density_chameleon_signature);
9797
}
9898

99-
DENSITY_WINDOWS_EXPORT DENSITY_FORCE_INLINE density_algorithm_exit_status density_chameleon_decode(density_algorithm_state *const restrict state, const uint8_t **restrict in, const uint_fast64_t in_size, uint8_t **restrict out, const uint_fast64_t out_size) {
99+
DENSITY_WINDOWS_EXPORT DENSITY_FORCE_INLINE density_algorithm_exit_status density_chameleon_decode(density_algorithm_state *const DENSITY_RESTRICT state, const uint8_t **DENSITY_RESTRICT in, const uint_fast64_t in_size, uint8_t **DENSITY_RESTRICT out, const uint_fast64_t out_size) {
100100
if (out_size < DENSITY_CHAMELEON_DECOMPRESSED_UNIT_SIZE)
101101
return DENSITY_ALGORITHMS_EXIT_STATUS_OUTPUT_STALL;
102102

@@ -113,12 +113,12 @@ DENSITY_WINDOWS_EXPORT DENSITY_FORCE_INLINE density_algorithm_exit_status densit
113113
const uint8_t *in_limit = *in + in_size - DENSITY_CHAMELEON_MAXIMUM_COMPRESSED_UNIT_SIZE;
114114
uint8_t *out_limit = *out + out_size - DENSITY_CHAMELEON_DECOMPRESSED_UNIT_SIZE;
115115

116-
while (density_likely(*in <= in_limit && *out <= out_limit)) {
117-
if (density_unlikely(!(state->counter & 0xf))) {
116+
while (DENSITY_LIKELY(*in <= in_limit && *out <= out_limit)) {
117+
if (DENSITY_UNLIKELY(!(state->counter & 0xf))) {
118118
DENSITY_ALGORITHM_REDUCE_COPY_PENALTY_START;
119119
}
120120
state->counter++;
121-
if (density_unlikely(state->copy_penalty)) {
121+
if (DENSITY_UNLIKELY(state->copy_penalty)) {
122122
DENSITY_ALGORITHM_COPY(DENSITY_CHAMELEON_WORK_BLOCK_SIZE);
123123
DENSITY_ALGORITHM_INCREASE_COPY_PENALTY_START;
124124
} else {
@@ -157,7 +157,7 @@ DENSITY_WINDOWS_EXPORT DENSITY_FORCE_INLINE density_algorithm_exit_status densit
157157
break;
158158
}
159159

160-
if (density_unlikely(shift == density_bitsizeof(density_chameleon_signature)))
160+
if (DENSITY_UNLIKELY(shift == density_bitsizeof(density_chameleon_signature)))
161161
goto read_signature;
162162
else
163163
goto read_and_decode_4;

0 commit comments

Comments
 (0)