C++ 通过添加指针进行复制可能会导致缓存丢失?
我想知道是否有人能解释一下这里发生了什么,以及一个可能的解决方案的建议C++ 通过添加指针进行复制可能会导致缓存丢失?,c++,visual-studio-2010,pointers,C++,Visual Studio 2010,Pointers,我想知道是否有人能解释一下这里发生了什么,以及一个可能的解决方案的建议 使用VS2010 ULIMATE C++ WIN X64。 英特尔i5-3570@3.4ghz,8GB内存 我有一段代码运行缓慢的问题,这让我很惊讶,因为它实际上并没有做太多。至少我还是这么想的。因此,使用一些老式的计时技术,我将问题缩小到了一个简单的内存添加和复制。使用混合源代码和程序集的选项调试输出,我得到这个 byte* pback = (byte*)m_pBackbuffer; 000007FEF5661A5E m
使用VS2010 ULIMATE C++ WIN X64。 英特尔i5-3570@3.4ghz,8GB内存
我有一段代码运行缓慢的问题,这让我很惊讶,因为它实际上并没有做太多。至少我还是这么想的。因此,使用一些老式的计时技术,我将问题缩小到了一个简单的内存添加和复制。使用混合源代码和程序集的选项调试输出,我得到这个byte* pback = (byte*)m_pBackbuffer;
000007FEF5661A5E mov rdx,qword ptr [rbx+0CA800h]
000007FEF5661A65 mov ebp,eax
byte* pout = (byte*)pSamplebuffer;
while(i--){
000007FEF5661A67 test esi,esi
000007FEF5661A69 je AVNOnScreenRenderer::MergeBackbufferToOutputSample+70h (7FEF5661A80h)
000007FEF5661A6B nop dword ptr [rax+rax]
*pout++ = (*pback++ + *pout);
000007FEF5661A70 movzx ecx,byte ptr [rdx]
000007FEF5661A73 inc rdi
000007FEF5661A76 inc rdx
000007FEF5661A79 add byte ptr [rdi-1],cl
000007FEF5661A7C dec esi
000007FEF5661A7E jne AVNOnScreenRenderer::MergeBackbufferToOutputSample+60h (7FEF5661A70h)
那一小段代码大约需要100毫秒才能完成
其中,删除+指针算法会将代码速度降低到0毫秒-使用以下代码:
byte* pback = (byte*)m_pBackbuffer;
000007FEF5661A5E mov r8,qword ptr [rbx+0CA800h]
000007FEF5661A65 mov ebp,eax
byte* pout = (byte*)pSamplebuffer;
while(i--){
000007FEF5661A67 test edi,edi
000007FEF5661A69 je AVNOnScreenRenderer::MergeBackbufferToOutputSample+71h (7FEF5661A81h)
000007FEF5661A6B nop dword ptr [rax+rax]
*pout++ = (*pback++);// + *pout);
000007FEF5661A70 movzx ecx,byte ptr [r8]
000007FEF5661A74 inc rsi
000007FEF5661A77 inc r8
000007FEF5661A7A dec edi
000007FEF5661A7C mov byte ptr [rsi-1],cl
000007FEF5661A7F jne AVNOnScreenRenderer::MergeBackbufferToOutputSample+60h (7FEF5661A70h)
我本来以为时间消耗很小,但是加上了。起初我认为这是因为我读写同一个内存地址,循环中的*pout变量,但后来我创建了另一个缓冲区来写,并重新安排了一些部分以使用其他变量,但问题仍然存在。当我删除+,问题就消失了
请一些聪明的人帮我解决这个问题
ps这里有一个用另一个缓冲区重新排列代码的例子
byte* pback = (byte*)m_pBackbuffer;
byte* pout = (byte*)m_pOutbuffer;
while(i--){
int b = *pback;
int s = *pSamplebuffer;
int o = b;//b + s;
*pout = o;
}
您确定上面打印的程序集等于最后执行的代码吗?智能编译器应该用简单的
memcpy
替换第二个版本,从而从本质上加快代码的速度。对于第一个代码段,这种优化是不可能的
根据缓冲区的大小,迭代每个元素并应用
add
操作确实会消耗一些时间。您不应该这样做吗,例如*pout++=o
?为什么要使用所有的临时变量?是的,很抱歉这是在论坛中输入的一个错误,上面的代码与程序集输出的原始源代码交错。临时工?只需测试100种不同的东西就可以找到问题所在,即当代码中使用b+s时,100毫秒的速度会减慢,而不考虑增加*pout变量。嗨,我已经发布了在visual studio中设置断点和检查反汇编的输出。缓冲区是1280*48*2字节。它从一些代码做一个基本的像素混合与2 yuyv图像,我需要做的实时。一个要求是缓冲区进入我的代码,并将我的代码留在cpu内存中,改变这一点是我无法控制的(我想到的是gpu计算替代方案),并且在评测代码时也使用调试版本?VisualStudio将为调试和发布模式生成两个不同的可执行文件。如果您想要有意义的度量,您应该更喜欢启用了优化的发布版本。是的,您的回答是正确的,发布的代码确实是调试版本。我已经尝试了所有优化打开的发布版本。它减少了几毫秒,但没有什么值得一提的。我还没有检查组件,因为我认为问题仍然存在。我认为缓冲区并没有那么大,不会对性能产生那么大的影响——这是一个巨大的影响,你同意吗?我使用了调试版本来分析代码。它指向一个调用这个函数的函数。因此,使用旧的测试方法——在循环之前取毫秒,在循环结束后取毫秒,得出结论,这段代码是瓶颈。量子世界中一定有奇怪的事情发生。我把这段代码放到了生产应用程序中,它的处理速度比我想象的要快得多,运行速度为0ms。没什么印象,但我很高兴这一切都很好。感谢您抽出时间回复。