C++ Visual Studio优化中断SDL图形输出
在Visual Studio中编译使用SDL-2并启用优化的芯片8模拟器时,SDL窗口无法显示任何图形。在未经优化的情况下进行编译时,SDL窗口完全工作 我对二进制文件进行了反汇编,以查看是否能够了解优化程序到底在做什么,反汇编时优化代码和未优化代码之间的唯一区别是两行rdata,如下所示: 优化:C++ Visual Studio优化中断SDL图形输出,c++,visual-studio,assembly,sdl-2,C++,Visual Studio,Assembly,Sdl 2,在Visual Studio中编译使用SDL-2并启用优化的芯片8模拟器时,SDL窗口无法显示任何图形。在未经优化的情况下进行编译时,SDL窗口完全工作 我对二进制文件进行了反汇编,以查看是否能够了解优化程序到底在做什么,反汇编时优化代码和未优化代码之间的唯一区别是两行rdata,如下所示: 优化: .rdata:140006914 2f 0x2f '/' .rdata:140006915 55
.rdata:140006914 2f 0x2f '/'
.rdata:140006915 55 0x55 'U'
未经选择:
.rdata:140006914 ce 0xce
.rdata:140006915 56 0x56 'V'
我在x86汇编方面没有太多经验,因此不理解这种差异会带来什么,以及为什么它会破坏东西
此外,恢复到我认为有效的前一个提交也会以同样的方式中断,使用有效的前一个编译的二进制文件也会以同样的方式中断。这让我想知道这是否可能是来自Windows的问题
这两条rdata行究竟如何对应用程序产生如此显著的影响?我将如何着手解决这一问题
我不确定确切的问题,但是 当编译器看到如下内容时:
int loopDisplay(void) {
while (running) {
if (chip8.drawFlag) {
UpdateDisplay(); // Update Display
chip8.drawFlag = false; // Reset Draw Flag
}
}
return 0;
}
int loopDisplay(void) {
temp = chip8.drawFlag;
if(running && temp)
UpdateDisplay(); // Update Display
}
}
while(running) {}
chip8.drawFlag = false;
return 0;
}
它将查找chip8.drawFlag等变量的详细信息,意识到它没有什么特别之处,它是一个纯布尔drawFlag;;然后优化代码,使其更像这样,其中temp可能只是CPU寄存器中的一个值:
int loopDisplay(void) {
temp = chip8.drawFlag;
while (running) {
if (temp) {
UpdateDisplay(); // Update Display
temp = false; // Reset Draw Flag
}
}
chip8.drawFlag = temp;
return 0;
}
然后它会意识到它可以对它进行更多的优化,也许会想出这样的办法:
int loopDisplay(void) {
while (running) {
if (chip8.drawFlag) {
UpdateDisplay(); // Update Display
chip8.drawFlag = false; // Reset Draw Flag
}
}
return 0;
}
int loopDisplay(void) {
temp = chip8.drawFlag;
if(running && temp)
UpdateDisplay(); // Update Display
}
}
while(running) {}
chip8.drawFlag = false;
return 0;
}
当然,如果running也只是一个普通的旧变量,那么它可以决定函数要么不执行任何操作,立即返回,要么永远循环,永远不执行chip8.drawFlag=false,永远不返回
要解决这类问题,即两个或多个线程在没有任何同步的情况下使用相同的东西,您需要告诉编译器变量是特殊的,例如,在使用它们之前获取一个锁,或者使它们成为原子。您必须检查所有代码并找出所有问题。没有太多的x86汇编经验。rdata用于只读数据,而不是x86指令。因此,查看初始化数据并搜索这些字节,也许你会得到一个关于它们作为小数、十六进制、字符串的一部分的clueLook,将它们还原为LE vs BE…一如既往,我们需要一个。也许更好的方法是调试未编译的代码,看看是否有错误……快速查看源代码会让我怀疑线程存在重大问题。例如,一个chip8.drawFlag被多个线程使用,不受任何类型的锁/互斥的保护,不是原子性的,甚至不是易失性的。看起来我需要解决我的线程安全问题,添加线程锁或使draw标志原子化可以解决我的问题。谢谢