Is there a way to broadcast an object or will I have to bcast all of the values it contains some other way?
I'll assume C++ language as only language having objects and defined MPI interface in standard. If I wrong, just say. For other languages basic principle is like this.
Basically, if you can do a memcpy of the object or store it into file (write) and read it from the file (read), you can do an MPI_Bcast of the memory, in which object is stored.
To be able of doing this, your object should
be composed with Only POD types (plain old data: char, int, float, double) or other objects with the same property
have no pointers inside it, because after sending to another MPI process, memory will be not the same as in sending process.
If your object is more complex, it should be serialized (marshalled) to some buffer before sending and deserialized (unmarshalled) after receive. You can use boost serialization - but even this variant is not universal (there are limits on how object can be organized to be serializable)
PS boost serialization is integrated into Boost.MPI
Related
I need to store a object describing the memory details of a memory block allocated by sbrk(), at the beggining of the memory block itself.
for example:
metaData det();
void* alloc = sbrk(sizeof(det)+50000);
//a code piece to locate det at the beggining of alocate.
I am not allowed to use placement new, And not allowed to allocate memory using new/malloc etc.
I know that simply assigning it to the memory block would cause undefined behaviour.
I was thinking about using memcpy (i think that can cause problems as det is not dynamicly allocated).
Could assigning a pointer to the object at the beginning work (only if theres no other choise), or memcpy?
thanks.
I am not allowed to use placement new
Placement new is the only way to place an object in an existing block of memory.
[intro.object] An object is created by a definition, by a new-expression, when implicitly changing the active member of a union, or when a temporary object is created
You cannot make a definition to refer to an existing memory region, so that's out.
There's no union, so that's also out.
A temporary object cannot be created in an existing block of memory, so that's also out.
The only remaining way is with a new expression, and of those, only placement new can refer to an existing block of memory.
So you are out of luck as far as the C++ standard goes.
However the same problem exists with malloc. There are tons of code out there that use malloc without bothering to use placement new. Such code just casts the result of malloc to the target type and proceeds from there. This method works in practice, and there is no sign of it being ever broken.
metaData *det = static_cast<metaData *>(alloc);
On an unrelated note, metaData det(); declares a function, and sizeof is not applicable to functions.
Every time when I call the generate_directed_packet a new object is created. Should I worry about deleting the packet object, before creating the next one. If so, how should I go about deleting the packet object?
function void generate_directed_packet();
packet = new();
void'(packet.randomize());
endfunction : generate_directed_packet
SystemVerilog has automatic memory management. That means it only holds an object around as long as there is a class variable containing a handle to that object. The simulator "deletes" the object after there are no more class variables with a handle to that object. The "delete" is in quotes because you have no knowledge of when it deletes the object. More likely it keeps the space around until another new() of the same object and reclaims the space.
If you are using the UVM, the typical case is you are generating packets in a sequence, and sending them to a driver. What you are really doing is creating a handle to a new object in the sequence, and then copying the handle from variables in the sequence to variables in the driver.
As you copy the handle from one variable to another, you are erasing the reference to the older object. So as long as you are put putting handles to your objects in data structure that grows as you add more object handles to it, the space from the old objects get reclaimed.
My class looks like this:
(defclass matrix ()
((rows :initarg :rows :initform 2)
(cols :initarg :cols :initform 2)
(matrix :accessor matrix)))
I have a specialisation of the initialize-instance method which creates the object for the matrix slot by calling into a c++ library. I have a matrix-destroy function which will free the memory allocated in c++.
What I want is to be able to get the garbage collector to call matrix-destroy on the matrix slot. Is there an idiomatic way to do this in common lisp?
In order to run a function after the garbage collector has collecte an object, you need to set a finalizer for that object. The Common Lisp standard does not include finalizers, but implementations do provide them. There is a compatibility library called Trivial Garbage that you can use to set them portably.
Setting a finalizer happens by simply calling FINALIZE on the object you want to attach the finalizer to. The finalizer function must not contain any references to the object itself, as that would prevent it from ever being collected. You should also keep in mind that the finalizer may be executed at any time in any thread, so it should be re-entrant and not depend on any specific dynamic environment.
SBCL manual has a short example for finalizers in 7.4 Garbage Collection. You can also see some existing project that uses them, such as cl-sdl2, which uses them to free SDL surfaces, textures and such. See SDL-COLLECT for where the finalizer is set, and CREATE-RGB-SURFACE for an example of where SDL-COLLECT is called from.
HashMap vs ConcurrentHashMap, when the value is AtomicInteger or LongAdder, is there any harm in using HashMap in a multithreaded environment ?
Yes, there is.
An object being of type AtomicInteger or LongAdder just means that the object itself is safe in a concurrent modification operation (i.e. if two threads try to modify it, they will do so one after the other). However, if the map containing the objects itself is of type 'HashMap', then concurrent modification operations of the map are not safe. For instance, if you want to add a key-value pair only if the key doesn't already exist in the map, you cannot safely use the putIfAbset() operation anymore because it's not synchronized/thread-safe in HashMap. And if you do use it, then it is possible that two threads will execute call this method at the same time, both of them reaching the conclusion that the map doesn't have they key, and then both of them adding a key-value pair, resulting in one of them overwriting the other other's value.
You cannot use a HashMap in a multithreaded environment. The reason is as follows:
If multiple threads operate on a simple HashMap they can damage the internal structure of the HashMap which is an array of linked lists. The links can go missing or go in circles. The result will be that the HashMap will be totally unusable and corrupt. This is the reason you should always use a concurrentHashMap in a multithreaded environment regardless of what value you want to store in the map itself.
Now, in a concurrentHashMap of a type say map< String val, 'any number'> 'any number' could be a LongAdder or an AtomicLong etc. Remember that not all operations on a concurrentHashMap are threadsafe by default. Therefore, if you use say a LongAdder then you could write the following atomic operation without any need to synchronize:
map.putIfAbsent(a string key, new LongAdder());
map.get("abc").increment();
According to JavaDoc of Object.hashCode() this method returns internal address of the object converting it to integer value.
But Garbage Collector can move the object from one memory segment to another changing it internal address. For example the object can be moved from Young Generation to Old Generation.
See for example the following command line keys of java.exe:
-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+UseParallelOldGC
-XX:+UseConcMarkSweepGC
They determine different algorithms of Garbage Collection.
Does it mean that in this case Object.hashCode() will return different values?
Or it will always return value corresponding to initial address of the object?
Straight from the javadoc
The general contract of hashCode is:
•Whenever it is invoked on the same object more than once during an
execution of a Java application, the hashCode method must consistently
return the same integer, provided no information used in equals
comparisons on the object is modified. This integer need not remain
consistent from one execution of an application to another execution
of the same application.