refactor cudaEvent usage

- add `CudaEvent` which is a wrapper for cudaEvent_t
- solve problem that `cudaStreamWaitEvent` was called too often
- EventStream: add function `waitOn(CudaEvent)`

This pull request minimizes the overhead of the event system. (~ 3-5%)
I think the better way is to give back a copy. If we return a reference it is to easy to access not valid memory if the parent event is already destroyed.