Tag: en

SSE2 Vector Operation by Vlfeat

If you are writing something involving the math between vectors in C/C++, you may want to check out Vlfeat (http://vlfeat.org).

It is designed to be a library for Computer Vision related stuff, but it also bring you a wrapper for SSE2 acceleration for vector computation.

Say your original code for the calculation of vectors product looks like this:

float productOfVectors(const float *vecA, const float *vecB, const int dimension) {
   float value = 0.0f;
   for (int i = 0; i < dimension; i++)
   {
        value += (vecA[i] * vecB[i]);
   }
   return value;
}

It can save you time significantly by adding vlfeat to your project and replace it with this:

float productOfVectors(const float *vecA, const float *vecB, const int dimension) {
   float value = 0.0f;
   vl_eval_vector_comparison_on_all_pairs_f(&value, dimension, vecA, 1, vecB, 1, vl_get_vector_comparison_function_f(VlKernelL2));
   return value;
}

It's pretty easy but it really works. It takes use of the SSE2 instructions provided by your CPU which result in an non-trivial acceleration when you are doing large scale computation.

You can find more supported forms of calculation here, thanks for the developer's good job.

Setup dropbox without X

Assume you are accessing your server remotely through SSH.

1. Download the package, say you are using Ubuntu

$wget https://www.dropbox.com/download?dl=packages/ubuntu/dropbox_1.4.0_amd64.deb

2. Install the package

$sudo dpkg -i *dropbox_1.4.0_amd64.deb

3. Start Dropbox

$dropbox start

4. You will get an url to link your computer here, copy-and-paste into your web-browser. Restart your dropbox, all set :]

$dropbox stop
$dropbox start

I tried to open the url with w3m or lynx inside the terminal but failed.
It seems they don’t support Javascript well.

fstream issue under 64-bits cygwin

This is a question I posted on StackOverflow: fstream issue under 64-bits cygwin, glad to get help from Nemo on Stackflow, all credits goes to him.

The problem is when I use 64-bits g++ to compile the same piece of code, I get unexpected different result.

The source code looks like this:

#include 
#include 
using namespace std;

int main()
{
    int rows = 200;
    int cols = 200;
    float data[rows*cols];
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            data[i*cols+j] = i*cols+j;
        }
    }
    const char *file = "tmp.txt";
    ofstream fs(file);
    if (fs.is_open())
    {
        fs.write((char*)&rows, sizeof(int));
        cout << fs.tellp() << endl;
        fs.write((char*)&cols, sizeof(int));
        cout << fs.tellp() << endl;
        fs.write((char*)data, sizeof(float)*rows*cols);
        cout << fs.tellp() << endl;
        fs.close();
    }
    return 0;
}

I am writing two integers and a block of float values into a binary file. It prints out how many bytes it wrote.

The expected result is:

4
8
160008

All the actions were performed under Cygwin. When the code was compiled with g++.exe, the result is right.

But when I use x86_64-w64-mingw32-g++.exe (only by which can generate 64-bits binary), the result is wired.

4
8
160506

It is wired.

According to Nemo's answer, this is because by default fstream will be opened in binary mode under *nix. This also holds for 32 bits g++ under Cygwin, but not for 64 bits cygwin g++.

It leads to an unexpected behavior, fstream will replace some special bytes, say 'newline' in the binary data, with different special bytes, say 'unix-style newline'.

To solve this problem, replace the line

ofstream fs(file);

with

ofstream fs(file,ios_base::binary);

We can alter the content of the float data array to see what will happen.

#include 
#include 
using namespace std;

int main()
{
    int rows = 200;
    int cols = 200;
    float data[rows*cols];
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            data[i*cols+j] = 0;
        }
    }
    const char *file = "tmp.txt";
    ofstream fs(file);
    if (fs.is_open())
    {
        fs.write((char*)&rows, sizeof(int));
        cout << fs.tellp() << endl;
        fs.write((char*)&cols, sizeof(int));
        cout << fs.tellp() << endl;
        fs.write((char*)data, sizeof(float)*rows*cols);
        cout << fs.tellp() << endl;
        fs.close();
    }
    return 0;
}

The output is:

4
8
160208

It somehow supports the above explanation.