- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am trying to call the PCM library version 1.7 from java using JNI. The idea is simply as following:
1. Call the PCM to get BaiscCounterType(CoreCounter, Socketcounter,SystemCounter)
2. Run some Java Code
3. Call the PCM again to get the BasicCounter
4. Call the PCM to measure the diffrence. (getCyclesLostDueL2CacheMisses,getCyclesLostDueL3CacheMisses)
Now, the problem is that I get the same BasicCounterType in step 1 and 3 which causes invalid results in step 4.
The JNI C++ code methods are as following:
1. Here is the method I use to get the BasicCounterType (CoreCounter). This method calls the getSystemCounterState() in cpucounters.cpp. Please note that I return the pointer address of the counter only.
JNIEXPORT jlong JNICALL Java_org_jpcm_JpcmJNI_getSystemCounterState
(JNIEnv *, jobject)
{
return (long)&getSystemCounterState();
}
2. Then after executing some java code, the same method is invoked again to get the counter reading after that.
3. The two long values (Pointers for Before & After) are passed to the following method to get the L3 cach miss
JNIEXPORT jdouble JNICALL Java_org_jpcm_JpcmJNI_getCyclesLostDueL3CacheMisses
(JNIEnv *, jobject, jlong before, jlong after)
{
BasicCounterState* stateBefore;
BasicCounterState* stateAfter;
stateBefore= (BasicCounterState*)before;
stateAfter = (BasicCounterState*)after;
return getCyclesLostDueL3CacheMisses((*stateBefore),(*stateAfter));
}
________________________________________________________________
The problem is that I get the same CoreCounter each time I call the PCM. By the wrod Same, I mean that I get the same Pointer Address Value (long) each time.
Any ideas how to solve that.
regards,
Amr
I am trying to call the PCM library version 1.7 from java using JNI. The idea is simply as following:
1. Call the PCM to get BaiscCounterType(CoreCounter, Socketcounter,SystemCounter)
2. Run some Java Code
3. Call the PCM again to get the BasicCounter
4. Call the PCM to measure the diffrence. (getCyclesLostDueL2CacheMisses,getCyclesLostDueL3CacheMisses)
Now, the problem is that I get the same BasicCounterType in step 1 and 3 which causes invalid results in step 4.
The JNI C++ code methods are as following:
1. Here is the method I use to get the BasicCounterType (CoreCounter). This method calls the getSystemCounterState() in cpucounters.cpp. Please note that I return the pointer address of the counter only.
JNIEXPORT jlong JNICALL Java_org_jpcm_JpcmJNI_getSystemCounterState
(JNIEnv *, jobject)
{
return (long)&getSystemCounterState();
}
2. Then after executing some java code, the same method is invoked again to get the counter reading after that.
3. The two long values (Pointers for Before & After) are passed to the following method to get the L3 cach miss
JNIEXPORT jdouble JNICALL Java_org_jpcm_JpcmJNI_getCyclesLostDueL3CacheMisses
(JNIEnv *, jobject, jlong before, jlong after)
{
BasicCounterState* stateBefore;
BasicCounterState* stateAfter;
stateBefore= (BasicCounterState*)before;
stateAfter = (BasicCounterState*)after;
return getCyclesLostDueL3CacheMisses((*stateBefore),(*stateAfter));
}
________________________________________________________________
The problem is that I get the same CoreCounter each time I call the PCM. By the wrod Same, I mean that I get the same Pointer Address Value (long) each time.
Any ideas how to solve that.
regards,
Amr
Link Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Amr,
by "return (long)&getSystemCounterState();" you are returning address of a temporary object (SystemCounterState) returned by getSystemCounterState() function. In C++ using adresses of temporary objects is a bad idea: the object basically does not exist after your "return" anymore. You see the same pointer address value because the same memory region is used to store the temporary object by the compiler/runtime system.
Instead, you should copy not the address but the whole content of returned SystemCounterState object to Java and use these copies as getCyclesLostDueL3CacheMisses parameters (pointers to them).
Best regards,
Roman
by "return (long)&getSystemCounterState();" you are returning address of a temporary object (SystemCounterState) returned by getSystemCounterState() function. In C++ using adresses of temporary objects is a bad idea: the object basically does not exist after your "return" anymore. You see the same pointer address value because the same memory region is used to store the temporary object by the compiler/runtime system.
Instead, you should copy not the address but the whole content of returned SystemCounterState object to Java and use these copies as getCyclesLostDueL3CacheMisses parameters (pointers to them).
Best regards,
Roman
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Roman,
Thanks a lot for your prompt response. I am trying your suggestion.
Regards,
Amr
Thanks a lot for your prompt response. I am trying your suggestion.
Regards,
Amr
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Roman,
I have tried your approach, and now the CPP JNI code returns the full data of BasicCounterType. This requried having a Java model for BasicCounterState class.
Please note that I get the error PCM::MSRAccessDenied How can I fix that? Does this has to do anything with the following case?
Looking into the Data returned from CPP here are the two BasicCounterState obtained before and After
BasicCounterState [instRetiredAny=0, cpuClkUnhaltedThread=0, cpuClkUnhaltedRef=0, l3Miss=43981, event0=43981, archLLCRef=43981, l3UnsharedHit=0, event1=0, archLLCMiss=0, l2HitM=0, event2=0, l2Hit=0, event3=0, invariantTSC=31392333685000]
BasicCounterState [instRetiredAny=0, cpuClkUnhaltedThread=0, cpuClkUnhaltedRef=0, l3Miss=43981, event0=43981, archLLCRef=43981, l3UnsharedHit=0, event1=0, archLLCMiss=0, l2HitM=0, event2=0, l2Hit=0, event3=0, invariantTSC=31401913898752]
Are these reasonable Data?
I can see that the following members have the same value:
1. l3Miss
2. event0
3. archLLCRef
and the invariantTSC has a diffrent values.
Does this mean that these e members are pointers to the desired data?
Thanks alot for your valuable help. Really appreciated.
Regards,
amr
I have tried your approach, and now the CPP JNI code returns the full data of BasicCounterType. This requried having a Java model for BasicCounterState class.
Please note that I get the error PCM::MSRAccessDenied How can I fix that? Does this has to do anything with the following case?
Looking into the Data returned from CPP here are the two BasicCounterState obtained before and After
BasicCounterState [instRetiredAny=0, cpuClkUnhaltedThread=0, cpuClkUnhaltedRef=0, l3Miss=43981, event0=43981, archLLCRef=43981, l3UnsharedHit=0, event1=0, archLLCMiss=0, l2HitM=0, event2=0, l2Hit=0, event3=0, invariantTSC=31392333685000]
BasicCounterState [instRetiredAny=0, cpuClkUnhaltedThread=0, cpuClkUnhaltedRef=0, l3Miss=43981, event0=43981, archLLCRef=43981, l3UnsharedHit=0, event1=0, archLLCMiss=0, l2HitM=0, event2=0, l2Hit=0, event3=0, invariantTSC=31401913898752]
Are these reasonable Data?
I can see that the following members have the same value:
1. l3Miss
2. event0
3. archLLCRef
and the invariantTSC has a diffrent values.
Does this mean that these e members are pointers to the desired data?
Thanks alot for your valuable help. Really appreciated.
Regards,
amr
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
amr,
the counter values are not valid because of thePCM::MSRAccessDenied error. It seems that you application cannot access MSRs (model specific registers) for some reason. What OS are you using?
Roman
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Roman,
My OS is Ubuntu 11.10.
I had complied the msr.o and installed it using 'modprobe msr' , then changed the owner ship of the folders /dev/cpu recursivly.
Amr.
My OS is Ubuntu 11.10.
I had complied the msr.o and installed it using 'modprobe msr' , then changed the owner ship of the folders /dev/cpu recursivly.
Amr.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Amr,
can you see the counter values using pcm.x utility (part of Intel PCM)?
Roman
can you see the counter values using pcm.x utility (part of Intel PCM)?
Roman
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Roman,
thanks for your help. I reinstalled the msr again and it worked fine with me.
I do have another question about the program() method can I ask it here or open a new thread?
I noticed that the number of PCM instance is increasing with each call. my question is should I call the program() method only one time, or call it any time then cleanup() after, or there is no need to call program() at all?
thanks for your help. I reinstalled the msr again and it worked fine with me.
I do have another question about the program() method can I ask it here or open a new thread?
I noticed that the number of PCM instance is increasing with each call. my question is should I call the program() method only one time, or call it any time then cleanup() after, or there is no need to call program() at all?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Amr,
you should call program() to initialize PCM once in the beginning of your program runtime and call cleanup() when you do not need PCM anymore in your program (e.g. before your program exits). Then the count of PCM instances should not increase each time.In thepcm.x example, theprogram() call is calledoncein the very beginning and cleanup() is called once on exit (in the kill and Ctrl-C handler).
Roman
you should call program() to initialize PCM once in the beginning of your program runtime and call cleanup() when you do not need PCM anymore in your program (e.g. before your program exits). Then the count of PCM instances should not increase each time.In thepcm.x example, theprogram() call is calledoncein the very beginning and cleanup() is called once on exit (in the kill and Ctrl-C handler).
Roman
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot.
![](/skins/images/C4F7392A5C68ACA60290C9576F107044/responsive_peak/images/icon_anonymous_message.png)
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page