我正在使用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中共享变量的访问吗?还是有其他方法可以减少运行时的开销?