I am experimenting with performance evaluation. From the hardware architecture point of view, two main factors are cache misses and incorrect prediction of conditional branches which can degrade the performance of an application.
I have considered a small application for each case:
Cache Misses:
In this application, I intentionally want to write such a piece of code that would cause a worst case scenario w.r.t. cache (i.e., induce cache misses). A cache miss can be a read miss or a write miss, so I have written the code for both.
Read Misses:
int n = 32767;
int arr[n];
for (int i = 0; i < n ; i++) {
int ri = rand() % n;
int var=arr[ri];
}
Write Misses:
int n = 32767;
int arr[n];
for (int i = 0; i < n ; i++) {
int ri = rand() % n;
arr[ri] = ri;
}
Branch Incorrect Predictions:
Here, I intentionally want to write such a piece of code that would cause a worst case scenario w.r.t. branch prediction (i.e., induce incorrect predictions). So, it will make the branch predictor fail badly. The code is as following: Source
const unsigned arraySize = 1024;
int data[arraySize];
for (unsigned c = 0; c < arraySize; ++c){
data[c] = std::rand() % 256;
}
long sum = 0;
for (int i = 0; i < 1024; ++i) {
// Primary loop
for (int c = 0; c < arraySize; ++c) {
if (data[c] >= 128)
sum += data[c];
}
}
My question:
- Can I make any improvements to these source codes?
(Since a flaw left at this level can make all my experimental results flawed.)
- What are other possible codes that would have similar behavior(cache misses and branch incorrect predictions)?
(Maybe, a couple of other possible ways to do the same thing but with different apparent code.)
- Last but not least; Is there any other potential factor (other than cache misses and branch incorrect predictions) that can cause such a huge performance degradation?
An example source code to demonstrate its effect on the performance.
Note: With regard to the third question, I can name factors e.g., interrupts, context switches etc., however, I am considering real-time paradigm where such events would presumably be controlled.
P.S. I know three different question should be asked in three different posts, nonetheless, the second question is an addendum to the first question and the third question alone will be dubious without the whole context.
Thanks.
EDIT: I am using gem5-simulator in my experiments. Just out of my mind, based on my previous studies and experiences, a brief description of the simulator is: It is a cycle-accurate simulator with the facility to configure customized platforms. The execution traces provided by this simulator does include the exact counts on most of the expected statistics (e.g., cache misses, branch incorrect predicted etc). The generation of these traces does not cause overhead on the actual execution of an application. It also provides overhead free instrumentation facility to added further counters in the traces as per user needs.
Nevertheless, @vnp: Adjoining thanks, I am getting the counts and considering the cache configurations.