我有一个正常运行的SSE代码,该代码通常是为Win64编译的(我使用的是Intel C ++编译器14)。完成后,该代码(由SSE内部函数组成)还执行性能计数操作。当我为Win32编译相同的代码时,此操作存在问题。
操作很简单:
LARGE_INTEGER Count;
QueryPerformanceCounter( &Count );
uint64_t v = Count.QuadPart;
printf( "%llu\n", v );
printf( "%f\n", (double) v );
第一个printf打印正确的64位值。第二个printf产生-1。#IND00。
如果我手动分配v,该错误就会消失。
针对可能的缓冲区不足/溢出和未初始化的访问检查了代码。不知道怎么了 在Win64上没有这样的错误。
编译器产生以下代码:在该块上:
;;; LARGE_INTEGER Count;
;;; QueryPerformanceCounter( &Count );
lea eax, DWORD PTR [1408+esp] ;152.1
push eax ;152.1
call DWORD PTR [__imp__QueryPerformanceCounter@4] ;152.1
; LOE ebx esi
.B1.94: ; Preds .B1.93
;;; uint64_t v = Count.QuadPart;
mov eax, DWORD PTR [1408+esp] ;153.14
mov edi, DWORD PTR [1412+esp] ;153.14
mov DWORD PTR [24+esp], eax ;153.14
;;; printf( "%llu\n", v );
push edi ;154.1
push eax ;154.1
push OFFSET FLAT: ??_C@_05A@?$CFllu?6?$AA@ ;154.1
call _printf ;154.1
; LOE ebx esi edi
.B1.344: ; Preds .B1.94
add esp, 12 ;154.1
; LOE ebx esi edi
.B1.95: ; Preds .B1.344
;;; printf( "%f\n", (double) v );
mov DWORD PTR [esp], OFFSET FLAT: ??_C@_03A@?$CFf?6?$AA@ ;155.1
mov eax, DWORD PTR [24+esp] ;155.1
mov DWORD PTR [32+esp], eax ;155.1
mov DWORD PTR [36+esp], edi ;155.1
fild QWORD PTR [32+esp] ;155.1
shr edi, 31 ;155.1
fadd QWORD PTR [_2il0floatpacket.1575+edi*8] ;155.1
fstp QWORD PTR [4+esp] ;155.1
call _printf ;155.1
但是,如果我在第二次printf之后重复此部分:
QueryPerformanceCounter( &Count );
v = Count.QuadPart;
printf( "%f\n", (double) v );
printf打印正确的值。汇编代码有些不同:
;;; QueryPerformanceCounter( &Count );
lea eax, DWORD PTR [1408+esp] ;156.1
push eax ;156.1
call DWORD PTR [__imp__QueryPerformanceCounter@4] ;156.1
; LOE ebx esi
.B1.97: ; Preds .B1.96
;;; v = Count.QuadPart;
;;; printf( "%f\n", (double) v );
fild QWORD PTR [1408+esp] ;158.1
mov eax, DWORD PTR [1412+esp] ;158.1
shr eax, 31 ;158.1
mov DWORD PTR [esp], OFFSET FLAT: ??_C@_03A@?$CFf?6?$AA@ ;158.1
fadd QWORD PTR [_2il0floatpacket.1575+eax*8] ;158.1
fstp QWORD PTR [4+esp] ;158.1
call _printf ;158.1
找到了解决方案:执行SSE计算后,应调用_mm_empty()函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句