從immintrin.h
,而不需要編寫內聯彙編使用int _rdrand64_step (unsigned __int64* val)
。你不需要它,有很多原因(包括本),以避免它:https://gcc.gnu.org/wiki/DontUseInlineAsm
在這種情況下,問題是,你可能編譯32位代碼,所以當然64位rdrand
是不可編碼的。但是你使用inline-asm的方式最終會給你一個32位的rdrand
,並在另一個寄存器中存儲垃圾。
gcc -Wall -O3 -m32 -march=ivybridge
(和鐺類似)產生(on Godbolt):
In function 'rdrand64_step':
7 : <source>:7:1: warning: unsupported size for integer register
rdrand64_step:
push ebx
rdrand ecx; setc al
mov edx, DWORD PTR [esp+8] # load the pointer arg
movzx eax, al
mov DWORD PTR [edx], ecx
mov DWORD PTR [edx+4], ebx # store garbage in the high half of *rand
pop ebx
ret
我猜你叫與碰巧有ebx=0
呼叫者此功能。否則你使用了一個不同的編譯器來做一些不同的事情。內聯後可能會發生其他事情。如果你看看反彙編你實際編譯的內容,你可以解釋到底發生了什麼。
如果你使用的內在,你會得到error: '_rdrand64_step' was not declared in this scope
,因爲只有immintrin.h
宣佈它在64位模式(並與-march
設置,意味着rdrand支持。或者[-mrdrnd
] 3。最佳選項:使用-march=native
如果您正在目標機器上構建)。
您也會得到顯著更有效的代碼爲重試循環,至少鏗鏘:
unsigned long long use_intrinsic(void) {
unsigned long long rand;
while(!_rdrand64_step(&rand)); // TODO: retry limit in case RNG is broken.
return rand;
}
use_intrinsic: # @use_intrinsic
.LBB2_1: # =>This Inner Loop Header: Depth=1
rdrand rax
jae .LBB2_1
ret
這避免了setcc,然後測試的是,這當然是多餘的。 gcc6具有用於從內聯asm返回標誌結果的語法。您也可以使用asm goto
並在asm中放置一個jcc,跳轉到label: return 1;
目標或落入return 0
。 (。內聯彙編文檔有這樣https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html的例子也the inline-assembly tag wiki見)
使用您的內聯彙編,鐺(在64位模式),它編譯於:
use_asm:
.LBB1_1:
rdrand rax
setb byte ptr [rsp - 1]
cmp byte ptr [rsp - 1], 0
je .LBB1_1
ret
(鏗鏘對包含內存在內的多個選項的約束做出錯誤的決定。)
gcc7.2和ICC17實際上最終得到了比asm更好的代碼。他們使用cmovc
得到0或1,然後test
。這很愚蠢。但這是一個gcc/ICC未能優化,希望是。
在哪個操作系統上,哪個版本的C++和哪個編譯器? C++ 11有[''](http://en.cppreference.com/w/cpp/numeric/random),更好地使用它(因爲它是可移植的)。 [Code :: Blocks](http://www.codeblocks.org/)不是*編譯器(它運行一個,也許是[GCC](http://gcc.gnu.org/)),而是一個IDE –
***我使用的編譯器是codeblocks *** Code :: Blocks是一個IDE。我假設編譯器是mingw的某個版本。 – drescherjm
Linux有'/ dev/random'參見[random(4)](http://man7.org/linux/man-pages/man4/random.4.html),[mingw](http:// mingw .org /)是 - 或者包含 - [GCC]的端口(http://gcc.gnu.org/)。在終端中運行'g ++ -v'或'g ++ --version'。最近足夠的mingw應該提供一個C++ 11編譯器 –