OS X Yosemiteで次のコードを実行しました。
unsigned long num_;
sysctl((int[]){CTL_HW, HW_PHYSMEM}, 2, &num_, &len, NULL, 0);
printf("AMT MEM: , %lu\n", num_);
そして戻ってきて140735340871680
これは言葉ではありません:(IPython 3で)
In [3]: mem / (1024 ** 3)
mem / (1024 ** 3)
Out[3]: 131070.0
16GBの物理メモリがあるからです。タイトルを見sysctl.h
ました。
#define HW_PHYSMEM 5 /* int: total memory */
#define HW_USERMEM 6 /* int: non-kernel memory */
今これは本当に言葉ではありません。合格すると、数字は信頼できますが、HW_USERMEM
具体的には合計メモリを要求しました。何を提供しますか?
私はPythonコードで愚かな数学ミスを犯しましたか?
答え1
私はPythonコードで愚かな数学ミスを犯しましたか?
実際に間違っているのはCコードです。
コードの最も簡単な修正は次のとおりです。
#include <stdio.h>
#include <sys/sysctl.h>
int main(void)
{
int64_t bytes;
size_t len = sizeof(bytes);
sysctl({ CTL_HW, HW_PHYSMEM64 }, 2, &bytes, &len, NULL, 0);
int megs = bytes / 1024 / 1024;
printf("AMT MEM: %d MiB\n", megs);
}
代わりにそれを使用すると、HW_PHYSMEM
バイト数は32ビットサイズと見なされる変数に格納されるため、RAMが最大2GiBのシステムでのみ機能します。 64ビットパラメータを変更するには、sysctl
以前のバージョンとの互換性が壊れるのを防ぐために新しい値が必要です。これがOpenBSDのsysctl(3)
マニュアルページでHW_PHYSMEM
使用されなくなったことを示している理由です。
上記のコードをいくつか変更しました。私は計算機を介して入力しなくても出力を読み取ることができるように、Cコードでいくつかの数学的な作業を行っています。また、わかりやすくするnum_
ために、いくつかの整数型警告を修正し、変数名を変更しましたbytes
。
このコードは一部のBSDでは正しく実行されますが、OS XまたはFreeBSDでは動作しません。
OS Xのマニュアルページを見ると、彼らはあなたが使用したいようです。sysctlbyname(3)
代わりに。ヨセミテではうまくいきます。
#include <stdio.h>
#include <sys/sysctl.h>
int main(void)
{
int64_t bytes;
size_t len = sizeof(bytes);
sysctlbyname("hw.memsize", &bytes, &len, NULL, 0);
int megs = bytes / 1024 / 1024;
printf("AMT MEM: %d MiB\n", megs);
}
16GiBの物理RAMがあり、16384MiBが正しく報告されます。
しかし、FreeBSDでこれを試してみると、答えは0になります。少し掘り下げると、hw.physmem
その逆を望むことがわかります。
もう一度我々は壁にぶつかった。それ sysctlbyname
OS Xの値は、あなたが見つけた一種の偽の結果を提供します。
したがって、結論として、これらすべてはシステムによって非常に異なるということです。クロスプラットフォームが必要な場合はたくさん#ifdefs
。
脚注:
申し訳ありません。まだ2の累乗を10億に少なくありません。 :)
OpenBSD 5.5 および NetBSD 6.0.1 でテストされました。