首页 > 解决方案 > 英特尔 Pin 多线程检测:如何仅检测线程之间的共享变量访问?

问题描述

我正在使用 Intel Pin 动态检测多线程程序以进行一些数据竞争检测。我检测内存读/写指令以在运行时收集内存跟踪,然后分析日志。跟踪收集很简单,它在运行时将内存跟踪(包括时间、线程 id、地址等)存储到缓冲区并在最后将其写入。

VOID PIN_FAST_ANALYSIS_CALL RecordMemRead(unsigned int  ip, unsigned int  addr, THREADID tid){
    PIN_GetLock(&lock,tid+1);

    membuf[instCounter].tid = tid;
    membuf[instCounter].ip = ip;
    membuf[instCounter].addr = addr;
    membuf[instCounter].op = 'R';
    instCounter++;

    PIN_ReleaseLock(&lock);
}

VOID PIN_FAST_ANALYSIS_CALL RecordMemWrite(unsigned int  ip, unsigned int   addr, THREADID tid){
  // similar to RecordMemRead()
}

VOID Instruction(INS ins, VOID *v){
    if(INS_IsBranchOrCall(ins)) 
        return;
    if(INS_IsStackRead(ins))
        return;
    if(INS_IsStackWrite(ins))
        return;  

    if (INS_IsMemoryRead(ins)){
        INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,  IARG_FAST_ANALYSIS_CALL, IARG_INST_PTR, IARG_MEMORYREAD_EA, 
          IARG_THREAD_ID, IARG_END);
    }

    else if(INS_IsMemoryWrite(ins)){
        INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite, IARG_FAST_ANALYSIS_CALL, IARG_INST_PTR, IARG_MEMORYWRITE_EA, 
          IARG_THREAD_ID, IARG_END);
    }
}

我的麻烦是严重的运行时开销(200x - 500x)。根据其他作品,跟踪收集应该只引入不到 100 倍的开销。我试图通过跳过对堆栈的访问来优化它,但这并没有太大帮助。由于我的仪器是在指令粒度上进行的,因此会记录大量访问。因此,我认为减少运行时开销的唯一方法是减少要收集的访问,也就是只记录对线程之间共享变量(与竞争相关的变量)的访问。

我可以通过某种方式找出对 Pin 中共享变量的访问吗?还是有其他方法可以减少运行时开销?

标签: multithreadinginstrumentationintel-pinoverhead-minimizationdata-race

解决方案


推荐阅读