Google グループは Usenet の新規の投稿と購読のサポートを終了しました。過去のコンテンツは引き続き閲覧できます。
表示しない

[Q] Maximum Array size

閲覧: 9 回
最初の未読メッセージにスキップ

Hiroki Kashiwazaki

未読、
2003/12/09 1:19:572003/12/09
To:
柏崎@北海道です。

# 何でもかんでも 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

Shinji KONO

未読、
2003/12/09 1:46:432003/12/09
To:
河野真治 @ 琉球大学情報工学です。

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,
河野真治 @ 琉球大学工学部情報工学科,

Hiroki Kashiwazaki

未読、
2003/12/09 2:32:432003/12/09
To:
柏崎@北海道です。

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を敢えて
使わなくても、とついつい思ってしまうのでした。

MOCHIDA Shuji

未読、
2003/12/09 2:41:192003/12/09
To:

持田@NETside です。

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. --

Shinji KONO

未読、
2003/12/09 3:38:122003/12/09
To:
河野真治 @ 琉球大学情報工学です。

うちでは、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 勉強するところから始めるんじゃないですかぁ?

tesi...@mtf.biglobe.ne.jp

未読、
2003/12/09 11:24:102003/12/09
To:
Hiroki Kashiwazaki <r...@cc.hokudai.ac.jp> writes:

> こういった配列の制限は主記憶容量(と他のプロセスが占有する資源)で
> 定まるのか、それとも何か他の要素があるのかどうにも良く分かっていま
> せん。皆様からの情報をお寄せ頂ければ幸いです。

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

KATAYAMA Yoshio

未読、
2003/12/09 6:37:232003/12/09
To:
片山@PFUです。

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

Hideki SAKAMOTO

未読、
2003/12/09 21:25:282003/12/09
To:
坂元です.

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

User Dohzono

未読、
2003/12/10 6:02:592003/12/10
To:
In article <7bllpl...@pulse.hlla.is.tsukuba.ac.jp>
Hideki SAKAMOTO <saka...@hlla.is.tsukuba.ac.jp> writes:

> # 以前はMAXPROCとかいうパラメータがあったような気がするのは気
> # のせい?

sysctl で出てくるこれですかね?

kern.maxproc: 1716

新着メール 0 件