# 何でもかんでも fj.comp.misc にするなと言われそうな…
要素数の大きい配列を作ろうとすると、LinuxのGCCでは[*1]コンパイラ時に
怒られ、FreeBSD のGCC では実行時にSIGABRTで終了してしまい、Solaris 8
のucbcc[*3]もFreeBSD同様、実行時に Killedで終了します。
件の配列は構造体配列で、
struct packet {
int nodenumber;
int destination;
int source;
char body [ 256 ];
}
のような、int * 3 + char * 256 により構成されています。この構造体を
上記のようなLinux 環境やFreeBSD 環境では30万程度作ると怒られ、或は
SIGABRT で終了され、Solaris 8上ではメモリある限りいくら作っても(100
万程度)怒られない模様です。Linux の主記憶は 512MB ですが、FreeBSD
では 2GB, Solaris 8 では 4GB です。
こういった配列の制限は主記憶容量(と他のプロセスが占有する資源)で
定まるのか、それとも何か他の要素があるのかどうにも良く分かっていま
せん。皆様からの情報をお寄せ頂ければ幸いです。
# その前に「そんなもの静的に確保するな」とか言われそうで恐い…。
[*1] Vine Linux 2.6r1 付属の gcc 2.95.3
[*2] FreeBSD 5.1R 上の gcc 3.2.2 [FreeBSD] 20030205
[*3] Solaris 8 Sparc 上の Sun Workshop 6 update 2 C 5.3
--
柏崎 礼生 (Hiroki Kashiwazaki)@HUIIC
Ph.D candidate in the Division of Electronics & Information
Engineering, Hokkaido University
mailto:r...@cc.hokudai.ac.jp
Tel:+81-11-706-2998
In article <86k756...@xh6.cc.hokudai.ac.jp>, Hiroki Kashiwazaki <r...@cc.hokudai.ac.jp> writes
> 要素数の大きい配列を作ろうとすると、LinuxのGCCでは[*1]コンパイラ時に
> 怒られ、FreeBSD のGCC では実行時にSIGABRTで終了してしまい、Solaris 8
> のucbcc[*3]もFreeBSD同様、実行時に Killedで終了します。
76MB程度ですか。elf の制限かなぁ。うちの Vine Linux では、
1000,000 でも問題ないです。login.conf はBSD/OSだし...
実行時の制限は、limit とかなんですが、Linux は、そのあたりの
デフォルトを決めているところがあるはずなんだけど、どこだった
かな。
> # その前に「そんなもの静的に確保するな」とか言われそうで恐い…。
もちろん。
struct packet *pool = (struct packet *)
malloc(sizeof(struct packet)*300000);
で、すむじゃないですか....
---
Shinji KONO @ Information Engineering, University of the Ryukyus,
河野真治 @ 琉球大学工学部情報工学科,
At 9 Dec 2003 06:46:43 GMT,
Shinji KONO wrote:
> 76MB程度ですか。elf の制限かなぁ。うちの Vine Linux では、
> 1000,000 でも問題ないです。login.conf はBSD/OSだし...
>
> 実行時の制限は、limit とかなんですが、Linux は、そのあたりの
> デフォルトを決めているところがあるはずなんだけど、どこだった
> かな。
limit の制限はほとんど unlimited で、
[reo@hoge reo]$ ulimit -d
unlimited
[reo@hoge reo]$ ulimit -f
unlimited
[reo@hoge reo]$ ulimit -l
unlimited
[reo@hoge reo]$ ulimit -s
8192
[reo@hoge reo]$ ulimit -t
unlimited
[reo@hoge reo]$ ulimit -v
unlimited
といった感じです。なんじゃろ。
> > # その前に「そんなもの静的に確保するな」とか言われそうで恐い…。
>
> もちろん。
>
> struct packet *pool = (struct packet *)
> malloc(sizeof(struct packet)*300000);
>
> で、すむじゃないですか....
malloc恐怖症に近いものがあっていつも避けてしまうのです....
確保する領域が動的に変更されない限りにおいて、mallocを敢えて
使わなくても、とついつい思ってしまうのでした。
NetBSD/i386 での様子です。参考までに。
% uname -srm
NetBSD 1.6P i386
% cc -v
Reading specs from /usr/pkg/gcc3/lib/gcc-lib/i386--netbsdelf/3.3/specs
Configured with: ./configure --prefix=/usr/pkg/gcc3 --host=i386--netbsdelf --enable-shared --enable-languages=c
Thread model: single
gcc version 3.3
% cc -DARLEN=1000000 -Wall -o a a.c
% ./a
55, G
% cc -DARLEN=8012998 -Wall -o a a.c
% ./a
zsh: cannot allocate memory: ./a
% cc -DARLEN=8012999 -Wall -o a a.c
a.c:13: error: size of variable `pkt' is too large
% echo '268 * 8012998' | bc
2147483464
% echo '268 * 8012999' | bc
2147483732
% echo '2^31' | bc
2147483648
% cat a.c
#include <stdio.h>
#ifndef ARLEN
#define ARLEN 1000000
#endif
struct packet {
int nodenumber;
int destination;
int source;
char body [ 256 ];
} pkt[ARLEN];
int main()
{
pkt[0].nodenumber = 55;
pkt[ARLEN -1].body[255] = 'G';
printf("%d, %c\n", pkt[0].nodenumber, pkt[ARLEN -1].body[255]);
return 0;
}
--
持田 修司 NETside Technologies Inc.
-- Equal Opportunity for All Good Architectures, NetBSD. --
うちでは、1100000ぐらいで落ちるみたい。
In article <ul83cbu...@pine.yorie.netside.co.jp>, MOCHIDA Shuji <moc...@netside.co.jp> writes
> % cc -DARLEN=8012998 -Wall -o a a.c
> % ./a
> zsh: cannot allocate memory: ./a
持田さん、それ、(singed) 32bit 越えてます....
ってことは、
struct packet {
int nodenumber;
int destination;
int source;
char body [ 256 ];
} pkt[ARLEN];
みたいな冗長な構造で30万も作るのは設計ミスだな。64bit machine
ならともかく。on-demand で作ったり再利用したりした方が良い
と思う。
やっぱり、malloc 勉強するところから始めるんじゃないですかぁ?
> こういった配列の制限は主記憶容量(と他のプロセスが占有する資源)で
> 定まるのか、それとも何か他の要素があるのかどうにも良く分かっていま
> せん。皆様からの情報をお寄せ頂ければ幸いです。
Linux だと、
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define ASIZE 3000000
struct packet {
int nodenumber;
int destination;
int source;
char body [ 256 ];
} ary[ASIZE];
int main()
{
char buf[100];
pid_t pid = getpid();
(void)sprintf(buf, "cat /proc/%d/maps", pid);
(void)system(buf);
(void)printf("\n&(ary[%d].body[255]) = %08x\n",
ASIZE-1, &(ary[ASIZE-1].body[255]));
return 0;
}
を実行した結果は、
08048000-08049000 r-xp 00000000 08:01 579 /home/tesigana/tmp/a.out
08049000-0804a000 rw-p 00000000 08:01 579 /home/tesigana/tmp/a.out
40000000-40016000 r-xp 00000000 08:01 210953 /lib/ld-2.2.2.so
40016000-40017000 rw-p 00015000 08:01 210953 /lib/ld-2.2.2.so
40017000-40018000 rw-p 00000000 00:00 0
40025000-4014b000 r-xp 00000000 08:01 32484 /lib/i686/libc-2.2.2.so
4014b000-40151000 rw-p 00125000 08:01 32484 /lib/i686/libc-2.2.2.so
40151000-40155000 rw-p 00000000 00:00 0
bfffe000-c0000000 rwxp fffff000 00:00 0
&(ary[2999999].body[255]) = 37f0a81f
ですので、静的配列を大きくとりすぎると /lib/i686/libc-2.2.2.so が
貼り付いている領域を破壊してしまうのでないかと。
---------------------------------------------------------------------
tesi...@mtf.biglobe.ne.jp
In Article <86k756...@xh6.cc.hokudai.ac.jp>,
Hiroki Kashiwazaki <r...@cc.hokudai.ac.jp> writes:
> 要素数の大きい配列を作ろうとすると、LinuxのGCCでは[*1]コンパイラ時に
> 怒られ、FreeBSD のGCC では実行時にSIGABRTで終了してしまい、Solaris 8
> のucbcc[*3]もFreeBSD同様、実行時に Killedで終了します。
>
> 件の配列は構造体配列で、
>
> struct packet {
> int nodenumber;
> int destination;
> int source;
> char body [ 256 ];
> }
Red Hat 7.1 (gcc 2.96) では、100万個作っても平気でした。
> のような、int * 3 + char * 256 により構成されています。この構造体を
> 上記のようなLinux 環境やFreeBSD 環境では30万程度作ると怒られ、或は
> SIGABRT で終了され、Solaris 8上ではメモリある限りいくら作っても(100
> 万程度)怒られない模様です。Linux の主記憶は 512MB ですが、FreeBSD
> では 2GB, Solaris 8 では 4GB です。
In Article <86fzfu...@xh6.cc.hokudai.ac.jp>,
Hiroki Kashiwazaki <r...@cc.hokudai.ac.jp> writes:
> At 9 Dec 2003 06:46:43 GMT,
> Shinji KONO wrote:
>
> > 76MB程度ですか。elf の制限かなぁ。うちの Vine Linux では、
> > 1000,000 でも問題ないです。login.conf はBSD/OSだし...
> limit の制限はほとんど unlimited で、
>
> [reo@hoge reo]$ ulimit -s
> 8192
auto変数になってたというオチだったりして、、、
--
片山@PFU
FreeBSDですと,上限の設定はカーネルコンフィギュレーションの
MAXDSIZでしょうか.
#
# Certain applications can grow to be larger than the 128M limit
# that FreeBSD initially imposes. Below are some options to
# allow that limit to grow to 256MB, and can be increased further
# with changing the parameters. MAXDSIZ is the maximum that the
# limit can be set to, and the DFLDSIZ is the default value for
# the limit. MAXSSIZ is the maximum that the stack limit can be
# set to. You might want to set the default lower than the max,
# and explicitly set the maximum with a shell command for processes
# that regularly exceed the limit like INND.
#
options MAXDSIZ="(256*1024*1024)"
options MAXSSIZ="(256*1024*1024)"
options DFLDSIZ="(256*1024*1024)"
指定しなかった場合のデフォルトの値は,4系列ですと,
/sys/i386/include/vmparam.h などにあります.5系列でも同じかど
うかは知りません.
余談ですが,プロセス数の上限やオープンできるファイル数の上限は
同じくカーネルコンフィギュレーション中のmaxusersの値で決まり,
その計算式は/sys/kern/subr_param.cにあります.以前シミュレーショ
ンで多数のファイルをオープンするプログラムを作って制限に引っ掛
かったときに調べました.
# 以前はMAXPROCとかいうパラメータがあったような気がするのは気
# のせい?
--
坂元 英紀 (Hideki Sakamoto)
e-mail: saka...@hlla.is.tsukuba.ac.jp
> # 以前はMAXPROCとかいうパラメータがあったような気がするのは気
> # のせい?
sysctl で出てくるこれですかね?
kern.maxproc: 1716