Hi,
When I include "clflush" instruction for out-of-order execution simulation
in MESITwoLevelCacheHeirarchy, it givis following error:

build/X86/mem/ruby/system/RubyPort.cc:433: fatal: Ruby functional read
> failed for address 0x1f2b80


Commenting out clflush operations seems to solve the problem. Any idea why
it could happen? does CLFLUSH properly implemented in Two Level MESI
protocol ?

I'm not proficient in gem5 debugging, but what I've observed is that this
fatal error is caused by some read request packet, surprisingly not any
flush request.  Also, If I commented out the fatal error message, system
gives warning as follows:

build/X86/mem/ruby/system/RubyPort.cc:267: warn: Cache maintenance
> operations are not supported in Ruby.


and completes execution, no crash or other type of error message. I don't
know what "Cache maintenance operations" means here and is it related to
the previous error.

I'm pretty confused and can't figure out how to approach. Anyone have any
suggestions ? I want to understand how clflush operation is simulated in
gem5 so that I could modify it for my research needs. I have attached my
configuration script and workload C++ file here.
#include <iostream>
#include <thread> 
#include <x86intrin.h>

#define PRINT 1
#define NUMBER_OF_THREAD 1
#define ArrSize 6

#if PRINT
    #define PrintValue(arg,...) {printf(" sample code " arg "\n",__VA_ARGS__);}
#else
    #define PrintValue(arg,...){}
#endif


#define FLUSH(arg) {_mm_clflush(arg);}
#define FENCE __asm__("mfence")

uint16_t* ARR = NULL;
uint64_t COUNTER;
inline void persis_barrier(){__asm__("mfence");}


void *threadFunction(void *argp){
    uint16_t thread_ID=*(uint16_t*)(argp);
    PrintValue("Inside Thread %d",thread_ID);
    for( int index = thread_ID;index <ArrSize;){
        ARR[index]=thread_ID;
        PrintValue("Executing clflush from thread %d",thread_ID);
        FLUSH(&ARR[index]);
        // PrintValue("Executing FENCE from thread %d",thread_ID);
        // FENCE;
        index += NUMBER_OF_THREAD;
    }

    PrintValue("Exiting Thread %d",thread_ID);
    return NULL;
}


void print_array(){
    PrintValue("%s","Starting Array Print");
    for(int i=0;i<ArrSize;i++){
        if((i)%20==0)std::cout<<"\n";
        std::cout<<ARR[i]<<"  ";
    }
    std::cout<<"\n";
}


int main(void){
    COUNTER = 0;
    ARR = (uint16_t *)malloc(ArrSize*sizeof(uint16_t));
    pthread_t *thrd = new pthread_t[NUMBER_OF_THREAD];
    uint16_t *thrdID = (uint16_t *)malloc(NUMBER_OF_THREAD*sizeof(uint16_t));
    for(uint16_t i=0; i<NUMBER_OF_THREAD; i++){
        thrdID[i]=i;
    }
    
    PrintValue("%s","Initiating Multiple threads\n");
     for(int i=0;i<NUMBER_OF_THREAD;i++){
         pthread_create(&(thrd[i]),NULL, threadFunction,&(thrdID[i]));
     }
     for(int i=0;i<NUMBER_OF_THREAD;i++){
         pthread_join(thrd[i], NULL);
     }
    // std::cout<<" Process Complete with COUNTER value "<<COUNTER<<std::endl;
    // print_array();
    delete ARR;
    return 0;
}
import os, argparse,sys 
from gem5.utils.requires import requires
from gem5.components.boards.simple_board import SimpleBoard
# from gem5.components.boards.x86_board import X86Board
from gem5.components.memory.single_channel import SingleChannelDDR3_1600
from gem5.components.processors.cpu_types import CPUTypes
from gem5.components.processors.simple_processor import SimpleProcessor
# from gem5.components.processors.simple_switchable_processor import SimpleSwitchableProcessor
from gem5.resources.resource import(  CustomResource, Resource, CustomDiskImageResource )
from gem5.resources.workload import Workload
from gem5.simulate.simulator import Simulator
from gem5.simulate.exit_event import ExitEvent


from gem5.isas import ISA
from gem5.coherence_protocol import  CoherenceProtocol
from gem5.components.cachehierarchies.ruby.mesi_two_level_cache_hierarchy import  MESITwoLevelCacheHierarchy



#################################
#########   Parameters ##########
#################################
#Memory
L1Cache = "32KiB"   # same size data and instruction cache
Asso_L1 = 4         # associativity
Asso_L2 = 8
L2Cache = "256KiB"      # 8 times of L1
L3Cache = "4096KiB"     #16 times of L2
DRAM_size = "1GiB"      


## config for interconnect netowrk
number_of_cpu = 4
number_of_dir = 4
network="garnet"
topology="Mesh_XY"
mesh_row=4




ClkFreq = "3GHz"
isa=ISA.X86


##################################


requires(
    isa_required=ISA.X86,
    coherence_protocol_required=CoherenceProtocol.MESI_TWO_LEVEL,
    kvm_required=True,
)




cache_hierarchy = MESITwoLevelCacheHierarchy(
    l1i_size=L1Cache,
    l1i_assoc=Asso_L1,
    l1d_size=L1Cache,
    l1d_assoc=Asso_L1,
    l2_size=L2Cache,
    l2_assoc=Asso_L2,
    num_l2_banks=1)
memory = SingleChannelDDR3_1600(DRAM_size)

processor = SimpleProcessor( cpu_type=CPUTypes.O3,
      num_cores=number_of_cpu,isa=isa)
# board = SimpleBoard(clk_freq=ClkFreq, processor=processor, memory=memory, cache_hierarchy=cache_hierarchy)
board = SimpleBoard(clk_freq=ClkFreq, processor=processor, memory=memory, cache_hierarchy=cache_hierarchy)



#simulation setup
# binary = CustomResource('tests/test-progs/hello/bin/x86/linux/hello')
binary = CustomResource('/compiled/workload/directory/fp')
board.set_se_binary_workload(binary)




#simulation start
simulator = Simulator(board=board)
# simulator =  Simulator(board=board,
#                        on_exit_event={
#                            ExitEvent.EXIT : (func() for func in [processor.switch]),
#                        },)
simulator.run()

Attachment: Makefile
Description: Binary data

_______________________________________________
gem5-users mailing list -- gem5-users@gem5.org
To unsubscribe send an email to gem5-users-le...@gem5.org

Reply via email to