HPX supports Active Global Address Space.Over a long period of time, I can't able to figure out what "AGAS" really is ? By doing some research with HPX-5 supported memory models. What I can able to see is in "AGAS: memory can be moved to other localities in order to balance the system" but in "PGAS" it is not able to do so. But in hpx we still create remote objects (components) with the parameter where to create it(Global identifiers of localities). But using HPX in desktop really hides this feature and also running HPX in rostam I can't able to differentiate it with "PGAS" memory system. Could you please help me to understand this black magic feature of HPX ?
You can think of AGAS as being a distributed key/value 'in memory' database.
When you create an object locally, you get a pointer of the standard variety that is referable using *this or this-> to get access to the internals.
However, you cannot pass a this pointer from one node to another and use it arbitrarily.
When you create an hpx:: component or register an object that you created with AGAS, it essentially stores the this pointer in the database and gives you an hpx::id_type as a handle (key). This id can be used in function calls on local or remote nodes as a way of referencing the object.
If you move the object from one node to another (using an agas function), then AGAS will update it's internal value to reflect the fact that the this pointer has changed value (it will internally have its destructor called locally and invoke a move of contents into a new one constructed elsewhere) and is located on another node, but the key - the id_type that you have for that object is still valid - note that this is only true if AGAS is doing the relocation - if you just create a copy elsewhere and delete a local object, it's not the same.
On a PGAS system, generally speaking, all the nodes share a block of memory with each other, and each node can 'access' memory/data/objects on the other node, by indexing into this shared memory area. So in PGAS, the addresses of items on other nodes are 'fixed' in the sense that data on node 1 is at shared_region + offset*1, data on node 2 is at + offset*2 and so on. This is a slight simplification, but you get the idea.
In HPX, objects are free to float about and you can reference them via the id_types and let AGAS handle the 'real' address lookups. That is why the 'Active' is in AGAS, as opposed to PGAS.
In this way data items (components) can be relocated from one place to another, but the handles that refer to them can be immutable.
In this sense the 'Address Space' part of AGAS is saying that hpx::id_type's can be thought of as addresses that span all the nodes in the job.
Related
I need to store an encoding-state value on a video while it's been encoded
I have a video object. While the video is being encoded it needs to lock edits on its comments.
The video therefore needs to store its current encoding state (is it happening yes/no?) and allow child comments to query that property.
Please note
I know that there are better ways to solve this particular problem. I actually need to solve a slightly different problem however I felt the nuances of it would confuse the question so I've chosen this one instead. My question is specifically around the nuances of isntance variables and not how to better-solve this encoding problem (which obviously needs a queue).
class Video
has_many :comments
after_initialize do
#encoding_in_process = false
end
def encode
#encoding_in_process = true
...
#encoding_in_process = false
end
def encoding_in_process?
#encoding_in_process
end
end
class Comment
belongs_to :video
before_update
raise "locked" if video.encoding_in_process?
end
...
end
As you can see, each video instance is storing an instance variable #encoding_in_process which is used to determine whether a comment can be updated.
The problem
There is a danger there will be multiple in-memory instances of the same video each with different values for #encoding_in_process.
e.g.
bieber_video = Video.find_all_by_artist('Bieber').last
bieber_video.encode
# assume this takes a while...
bieber_video.encoding_in_process?
# => true
bieber_copy = Video.find_by_id bieber_video.id
bieber_copy.encoding_in_process?
# => false
# Each ActiveRecord objects refer to the same Bieber video
bieber_copy.id == bieber_video.id
# => true
# ...however they refer to different objects in memory:
puts bieber_video
#<Video:0x00000105a9e948>
puts bieber_copy
#<Video:0x00000105a11111>
# and hence each instance has a different version of commenting_locked?
# bieber_video.encoding_in_process? != bieber_copy.encoding_in_process?
The question
Given that the same database row might generate two different in-memory instances, what is a safe way to store transient non-database-backed information about those instances?
EDIT
The actual problem I'm trying to solve is setting a flag on an object when destroy is initiated such that its child objects can determine whether or not they're eligible to be destroyed themselves.
It's therefore a very instantaneous problem and not suitable for backing into the database. I used this video example because I thought it was a bit clearer however I may have simply muddied the waters.
THE SOLUTION (courtesy of one of the answers below
#Alex D's suggestion did solve the problem but to add further clarity to this for anyone wanting to repeat, the actual code was this:
class Video
# set a class variable containing an array of all videos
# which are currently being encoded
##ids_of_videos_being_encoded = []
...
def encode
store_encoding_state true
begin
encode()
ensure
# make sure we switch this off after
# encoding finishes or fails
store_encoding_state false
end
end
private
def store_encoding_state encoding_in_progress
if encoding_in_progress
##ids_of_videos_being_encoded.push(id)
else
##ids_of_videos_being_encoded.delete(id)
end
end
def encoding_initiated?
##ids_of_videos_being_encoded.include? id
end
end
The answer to your question depends on whether you may use multiple server processes or not. If you may want to run multiple server processes (which is a good assumption), the problem is not just multiple in-memory ActiveRecord objects representing the same DB row, the problem is multiple objects in different memory spaces.
If you have multiple processes which are somehow collaboratively working with the same data, you must keep that data in a shared store (i.e. a database), and you must flush changes to the store, and refresh your in-memory data as needed. In this case, you cannot rely on transient in-memory data being kept in synchronization (because there is no way it possibly could be).
If constantly writing/reading your transient data to the DB sounds expensive, that's because it is. In general, whenever you have multiple processes (on the same or different servers) working together, you want to design things so each process can grab a chunk of data and work on it for a while without having to communicate with the others. Fine-grained data sharing in a distributed system = bad performance.
If you are sure that you will only ever use a single server process, and you want to simulate the effect of instance variables which are shared between multiple ActiveRecord objects representing the same DB row, keep the data in a hash, keyed by the record ID, and use getters/setters which read/write the hash. If you are doing a lot of this, you can do some metaprogramming "magic" to have the getters/setters automatically generated (a la "attr_accessor"). If you need help writing that metaprogramming code, post a question and I'll answer it.
The video therefore needs to store its current encoding state (is it happening yes/no?) and allow child comments to query that property.
IMO, that's not a good way to do this because of all the synchronization issues that will ensue.
A much better strategy is to start off all videos in an unencoded state, which you store with the video record's metadata. When a video data stream is created, enqueue an encoding task for some worker to carry out. The worker thread will encode the videos, and when it's done, it should update the video's state to encoded.
Now there's no transient state issues; the next time someone tries to comment when the encoding is finished, it'll be done.
Given that the same database row might generate two different in-memory instances, what is a safe way to store transient non-database-backed information about those instances?
If they don't need to be synchronized, then there isn't an issue. If they do need to be synchronized, you run the risk of a race condition. You can also call .reload to refresh an object's state from the database.
And if the data needs to be synchronized like that, then you probably do need to store it. In the video encoding example, you should either store each video's encoded/unencoded state or provide an implicit, authoritative way of knowing whether the video is encoded or not.
Update from the original question:
The actual problem I'm trying to solve is setting a flag on an object when destroy is initiated such that its child objects can determine whether or not they're eligible to be destroyed themselves.
Just use the after_destroy callback to invoke an appropriate method on each child object, and let them determine whether they should be destroyed or not. That will look something like this:
class Video < ActiveRecord::Base
after_destroy :purge_pending_comments!
def purge_pending_comments!
comments.map &:destroy_if_pending
end
end
Firstly, i am sorry if the title does not properly describe my problem, but i could not think of a better one. =/
I am trying to make a game where all entities that I need to draw on the screen are children of an Actor class.
The actor class has a virtual function called "virtual void drawMe()" that is overridden by the children to specify how it should be drawn.
Ergo, at the end of the game loop, I want to draw all actors. I created a "vector allActors" to help me with this and every time I create a new actor I do this: "allActors.push_back( &newActor )". So far so good (I think).
To draw them at the end of the loop I iterate through all elements in allActors and call "allActors[i]->drawMe()" for each one.
But I discovered that this method will not work for actors that I created locally, like the bullets created when the character shoots (they are created inside an if statement).
I think it is because while I save the address of the bullets in the allActors vector, the actors themselves are destroyed after the if statement ends, so it's an address to nothing.
example:
if ( characterShot == true)
{
Bullet newBullet;
allActors.push_back( &newBullet );
characterShot = false;
}
I have no idea of how to do this in a way that it works, because I can only create the bullet actors IF the character shoots!
Please help me figure out a better and more functional way to do what I want.
Thank you in advance!
Allocate the object dynamically:
allActors.push_back(new Bullet);
Note that the lifetime management will be a genuine nightmare; you should make the container elements some sort of smart pointer (ideally std::unique_ptr<Bullet> or some suitable base class).
You're right in your assumption that you're pushing an address to a local object that then goes out of scope. Doing this should cause your application to be quite unstable.
Allocate the object on the heap instead, using a smart pointer that keeps track of the lifetime of the object for you:
allActors.push_back(tr1::shared_ptr<Bullet>(new Bullet));
This gives you another problem: You have to remove the bullet from the allActors array once it hits the target.
Well I am a new to VB.NET, converting a legacy system to .NET world. Recently I have been reviewing the already existing code since I joined the project quite late in the team.
So I find that there are many shared functions (not shared class) inside many classes. I doubt this may create some problem if two requests ( i.e two different HTTP request to the same method as it's a WCF application, of course exposed methods are not shared but internally called methods are shared) comes to the same shared method and both the calls to the method may have different method parameters/arguments, overwriting each other's arguments.
In short, if shared method has a list of arguments which is going to be processed, is there any chance of inconsistencies in the light of multiple access to the shared method via two http requests.
I would appreciate each and every response the thread.
Thanks,
JJ
No.
Parameters are local to the method call and will not interact across threads.
However, if you use Shared fields or variables, you will have issues.
It is true that parameters are local to the method call; however, that will not necessarily limit their reach. Class variables sent as ByVal parameters can still result in interactions across threads. You may want to read up on the SyncLock keyword. The use of the Shared keyword will not affect (i.e. reduce) the chances of such interactions.
The main issue about multithreaded applications is when the very same range of memory gets referenced by more than one thread at a time, particularly when any one of those threads may make memory writes.
Some things to think about:
(1) Visual Basic (and C#) dichotomizes variables (and data types) into two species: the "Value" (or "Structure"), and the "Reference" (or "Class").
(2) The "Value" data type means that a direct reference is made to an actual collection of bits that represents an Integer, or a Boolean, or even a bitmap, or some other kind of object. In old school parlance, this is the "image" of an instantiation of an object. It is the state space of the object. It is what makes an object itself versus being some other object, independant of where in memory it may be.
(3) The "Reference" data type means that this a very special Structure which somehow indicates the data type of the object and where in memory it resides. The computer will interpret a "Reference" to obtain the actual image of the object.
(4) When a "Value" parameter is passed ByVal, that means a new object is created that is in the identical image of the original expression being passed, and it is upon this copy that the function or method operates. The image of the original "Value" cannot be affected.
(5) When a "Value" parameter is passed ByRef, that means a new "Reference" variable is created, and that "Reference" variable will contain the information that will interpret back to the image of the original "Value". Now the image of the original "Value" can be changed.
(6) When a "Reference" parameter is passed ByVal, the very special Structure, which gets interpreted back to the actual image of the object, gets copied. It is upon this copy of the very special Structure that the function or method operates. This copy still points to the actual image of the object. Which means that an object of a Reference variable that is passed by ByVal can still have its image (i.e. its "Value") changed. However, the very special Structure of the original "Reference" itself cannot be changed.
(7) Note that the String type is an odd duck: It will behave as if it were a "Value" parameter even though it is in fact a "Reference" type. Hence a String passed ByVal will not be affected in the same way any other class would. Actually, String is an example of an immutable type - which means that steps are taken to prevent changes to the image of its "Value". (See http://msdn.microsoft.com/en-us/library/bb383979.aspx and http://codebetter.com/patricksmacchia/2008/01/13/immutable-types-understand-them-and-use-them/ for more details.)
(8) When a "Reference" parameter is passed ByRef, one now has created a new "Reference" object that points to the original "Reference" object (that, in turn, points to the "Value" of some other object). The use of ByRef on a "Reference" allows one to modify (or create anew) the very special Structure of the original "Reference" object being passed as a parameter. A function or method that performs a swap operation will use ByRef on "Reference" parameters.
(9) Some people say that a "Reference" is the same as a memory address. While in particular cases this may in fact be true, technically it is not. The very special Structure does not have to be a memory address in whatever image would be valid for the CPU - although utlimately the computer will translate it into a valid memory address at some point.
(10) The keyword Me is an automatic "Reference" to the object that is currently executing the class member. Under the hood, it exists as a parameter too, one that is sent unseen. EXCEPT in the case of a Shared member - in which case Me is unavailable.
I've got a Registry class and there are a few Registry values that I want to access from within that Registry class. (There is a bit of a calculation with these values so I thought I'd just put all that code right in the Registry Class itself).
So we might have something within our RegistryRoutine.cls like:
Function GetMyValue() as integer
Dim R as new RegistryRoutine
<calculations>
GetMyValue=R.GetRegisetryValue (HKEY, key, value, etc.)
End Function
No, in general you won't see any problems (like member variables being overwritten or anything weird like that).
Where you could run into issues is if you have explicity shared variables that are being written to multiple times. But that's dangerous no matter what you do.
Do watch out for recursive cases - e.g., GetMyValue() should not call R.GetMyValue(), nor should GetRegistryValue() call GetMyValue().
It's rare that you actually want to do this, however.
Since you're not passing any arguments into GetMyValue(), we can assume that the current instance already has all the information it needs.
Since you're only returning an integer, not a RegistryRoutine instance, the client has no need for a new instance.
So, why not just call GetRegistryValue (without the R.)?
It's quite common for classes to work with instances of themselves. Consider, for example, how a tree structure works. Either a Node class has to keep track of its children, or has to keep track of its parent (or both). All the nodes are the same class.
Below is a code snippet that is creating object.
Form userexit_save_document_prepare.
data: /bks/exitmanager type ref to /bks/exit_manager.
create object /bks/exitmanager
exporting main_prog = 'SAPMV45A'
exit_form = 'USEREXIT_SAVE_DOCUMENT_PREPARE'.
include /bks/exitman.
ENDFORM.
I got this from the documentation
For performance reasons, the parameters "main_prog" and "exit_form" should be filled, in the case of userexits, which are performed very often like "user_field_modification" in "SAPMV45A" which is called for every single screen-field.
1) What happened exactly behind when create object /bks/exitmanager is called? memory allocated for the object etc?
2) Why for performance reasons the exporting parameters of create object needs to be filled?
I'm not 100% sure, but here is my best guess:
an object called /bks/exitmanager is constructed (which is an oject of the class /bks/exit_manager or more specific a reference/"pointer" to an object of this class) .. the required memory allocated etc., but also the "constructor" code is called (probably sets some instance variables as passed to the call).
If you're explicitly passing these parameters, they don't have to be "calculated" at run-time (e.g. by looking at the call stack). This should save some time, especially if it would have to be done quite often (as described in the documentation).
It would help to see what /bks/exit_manager actually is, and a brief explanation of what you are trying to accomplish.
Expanding on what IronGoofy wrote:
data: /bks/exitmanager type ref to /bks/exit_manager
This creates a reference pointer in the ABAP memory of your program, much like a field symbol. Also it must be already delared. If it is in the include, you need to move the include.
create object /bks/exitmanager
exporting main_prog = 'SAPMV45A'
exit_form = 'USEREXIT_SAVE_DOCUMENT_PREPARE'.
This creates an object instance based on the declared class, and assigns it to the referance pointer. It does this by calling the constructor method first.
Only by examing /bks/exit_manager will you find out exactly what you need to export.
It's impossible to tell what's going on and why the parameters should be passed without taking a look at the constructor of /BKS/EXIT_MANAGER. It's a common pattern though to keep a buffer of settings (think of a static hashed table with the key being the parameters and the value holding whatever is complicated and time-consuming to fetch). In this case, I would have expected a protected constructor that cannot be accessed directly, but only using a static factory method that uses a hashed table to keep the references of the exit handler itself - optimally using weak references...