mercredi 4 septembre 2013

C++11: Combining lambda and smart pointer to handle create/release API

I use a library in which several class use create/release pattern for memory and resources management. it means that there is no public constructor (ctor) and destructor (dtor).

Example:

class FileInterface
{
public:
virtual ~FileInterface() {}

virtual bool isValid() = 0 ;
virtual void release() = 0;
};

class RealFile : public FileInterface
{
public:
static int createFileInterface(const std::string& filename, FileInterface*& pFileInst)
{
try {
pFileInst = new RealFile(filename);
} catch (...){
return -1;
}
return 0;
}
virtual bool isValid() { return (m_pFile != NULL);}
virtual void release() { delete this;}

protected:
RealFile(const std::string& filename)
: m_pFile(NULL)
{
m_pFile = fopen(filename.c_str(), "wb");
if(m_pFile == NULL) {
throw std::runtime_error("error while opening file.");
}
}
~RealFile() {
std::cout << "DTOR" << std::endl;
fclose(m_pFile);
}
private:
FILE* m_pFile;
};





To use that kind of class you have to deal with the release by yourself. it means that if you have several return path or a complex exception management, you have to put a call to the release function everywhere (with additional check for  not null).

FileInterface* pFile = nullptr;
int ret = RealFile::createFileInterface("test.bin", pFile);
if( ..... )
{
....
std::cout << "isValid = " << pFile->isValid() << std::endl;
pFile->release();
return ...;
}
else
{
....
if(pFile != nullptr)
pFile->release();
return ...;
}



That’s why I like the C++ smart pointer, at allocation you define the custom deleter and when the smart pointer instance goes out-of the scope, everything will be free.

auto smartDeleter = [](FileInterface* ptr){ptr->release();};
auto smartAllocator = [](const std::string& filename) -> FileInterface* {
FileInterface* pFile = nullptr;
int ret = RealFile::createFileInterface(filename, pFile);
if (ret != 0) return nullptr;
else return pFile;
};

std::unique_ptr<FileInterface, decltype(smartDeleter)> smartFile(smartAllocator("test.bin"));
std::cout << "isValid = " << smartFile->isValid() << std::endl;



Now we can use the smartFile instance as a pointer on a FileInterface and let the life management responsibility to the unique_ptr.

IE–“Toolbars and extension management” (StExBar missing)

 

Sometime I don’t understand how Microsoft organize & manage the relation between the different program running under Windows (Seven) ?

I had an Explorer shell extension call StExBar and today after an update and the restart (as usual), it disappear and the in Explorer Menu (View –>ToolBar) I found it but it was grey and un-clickable !

After some Googling, I found some discussion in which users had the same issue. In fact depending of the version (x86 or x64) of the plugin or extension you use (the StExBar in my case) you can Enable/disable them through the x86 or the x64 version of Internet Explorer (a.k.a IE).

Open the right version of IE, ALT+T (Menu “Tools”) –> “Internet Options”

image

Go into “Programs'” and click ”Manage Add-ons”

image

It’s definitely not the place where I had search by myself to found enable/disable button for shell extension used only by Explorer.exe. I’m wondering in why those settings are in IE….

mercredi 21 août 2013

FFMPEG deprecated on Ubuntu .... it's not a joke !

As I created a new virtual PC to host a Ubuntu 12.04.2 LTS, I tried to setup all my favorites command line tools.

But after setting up ffmpeg: sudo apt-get install libav-tools
I asked for the version and got the following message:

ffmpeg version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, Copyright (c) 2000-2013 the Libav developers
built on Apr 2 2013 17:02:36 with gcc 4.6.3
*** THIS PROGRAM IS DEPRECATED ***
This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
ffmpeg 0.8.6-4:0.8.6-0ubuntu0.12.04.1
libavutil 51. 22. 1 / 51. 22. 1
libavcodec 53. 35. 0 / 53. 35. 0
libavformat 53. 21. 1 / 53. 21. 1
libavdevice 53. 2. 0 / 53. 2. 0
libavfilter 2. 15. 0 / 2. 15. 0
libswscale 2. 1. 0 / 2. 1. 0
libpostproc 52. 0. 0 / 52. 0. 0


ffmpeg .... DEPRECATED, it looks like the Ubuntu community push to replace the original ffmpeg command line by the avconv (a fork of ffmpeg....)
For me it's just a pain, as ffmpeg and avconv will not have the same development cycle, and their features and command line may vary, so switching from windows, to centos, to ubuntu and not having the same tools is terrible !

Will rebuild my own ffmpeg up-to-date instead of using the package manager !


mercredi 7 août 2013

How to use MS Live Writer with Blogger

 

  • Setup MS Live Writer that you can find here.
  • Start MS Live Writer.
  • On the first dialog box, select “Other Blog, Blogger etc…”.
  • On the second dialog box, for your blog URL, use your blog URL, but use HTTPS instead of HTTP. Fill correctly your username and password.
    • WARNING with 2-factor Authentication, you have to create a specific App password.

 

  • Next, Next, … All remaining Step are easy.

mercredi 31 juillet 2013

Replace STL Algorithm with "Parallel" Algorithm.

The goal is to keep a C++ syntax and STL style of writing code while using parallelism. It's a recent topic and lot of C++ Framework emerged in the 2 or 3 previous year.

 Note that an automatic replacement of all STL algorithm by a parallel equivalent isn't a good idea, so that in any case you will have to update your code.

in the following example, I just define a small lambda and apply that one on a 1d array using std::transform.
I called  a parallel version using the PPL(in the VS'2012). Only have 2 cores but seems lead to the expected factor 2.



#include <ppl.h>

void main ()
{
float otherScalingFactor = 0.3f;
#define size 59999999
float* local_arr = new float[size]; std::fill(local_arr, local_arr + size, 1.5f);
float* out = new float[size];
auto normalize = [&] (float x) { return fabs(x / otherScalingFactor) * otherScalingFactor + expf(x) * cosf(x) ; };
time_t start = time(NULL);
std::transform(local_arr, local_arr + size, out, normalize);
time_t end = time(NULL);
std::cout << "end in ..." << difftime(end, start) << std::endl;

std::fill(out, out + size, 0.0f);

start = time(NULL);
concurrency::parallel_transform(local_arr, local_arr + size, out, normalize);
end = time(NULL);
std::cout << "end in ..." << difftime(end, start) << std::endl;

delete [] local_arr;
delete [] out;

getchar();
}

mardi 30 juillet 2013

Producer - Consumer: a common conception error.

Producer-Consumer design or Pipeline of task are often use in programming to introduce multi-threading. But some programmer are wrong in the way they implement that. For example, I found the following question on Stackoverflow: concurrent_queue memory consumption exploded, then program crashed. The question is why the memory rise a limit so that the program crash !

After some comment, I finally post an answer, but I realize that it may be useful to explain a bit more with some schema.


If the producer run 2x faster than the consumer the number of element in the Fifo will grow linearly. So as in the real life, we have to specify a limited stock size. So that if the stock is full, the producer must wait.


That can be achieve with a dual synchronization:
  • Consumer wait if the fifo is empty and is awake if an element is pushed.
  • Producer wait if the fifo is full and is awake if an element is remove so that the size goes under the threshold.
For the code, see my answer on Stackoverflow!

dimanche 28 juillet 2013

Optimization - Where Meta-Programming can help...

In this post, I will show 2 different methods of computing the n-th element of the Fibonacci Suite.
The goal is to show that in some context instead of using run-time to compute something, you can compute that at compile-time.

  • run-time, is what you want to optimize.
  • compile-time, what you can increase (in some limit) without impact on your customer.
If compile-time become really too long, you will be depressed waiting in front of your computer. But your compiler can do a lot for you.

See below a simple recursive function to compute the n-th element of the Fibonacci suite.


int Fibonacci_recursive(int nieme)
{
if( 0 == nieme)
return 0;
if( 1 == nieme)
return 1;

return Fibonacci_recursive(nieme-1) + Fibonacci_recursive(nieme - 2);
}


Now if you use that function "Somewhere in your code", and disassemble the resulting binary, you will see something like:

00E91357 call Fibonacci_recursive (0E91270h)

The code you call use a lot of op-code and call itself several time depending of the element you ask. This kind of computation is not time-constant !

So it will be interesting if compiler can compute the value! At run-time we will have directly have the value in constant-time.... To achieve that goal, you can use Macro (Preprocesor), or Template (C++ Meta Programming). I choose the template way :


template<int I> struct Fibonacci_meta {
enum { value = Fibonacci_meta<I-1>::value + Fibonacci_meta<I-2>::value };
};
template<> struct Fibonacci_meta<1> {
enum { value = 1 };
};
template<> struct Fibonacci_meta<0> {
enum { value = 0 };
};


And now if you write Fibonacci_meta<10>::value in your code, and analyze the result, you will just see something like:

008F7BFF push 37h

And as you may know 0x37 == 55... the 10-th element of Fibonacci.
It's a simple example, but we removed several function call and have let the compiler find the result at compile-time!!!!