From Dries.Kimpe@XXXXXXXXXXXXXX Wed Jan 9 06:05:26 2008 Delivered-To: mpifrm-mpi-21-outgoing@XXXXXXXXXXXXXXXXXXXXXXX X-Original-To: mpifrm-mpi-21@XXXXXXXXXXXXXXXXXXXXXXX Delivered-To: mpifrm-mpi-21@XXXXXXXXXXXXXXXXXXXXXXX X-Greylist: delayed 1910 seconds by postgrey-1.21 at mailbouncer.mcs.anl.gov; Wed, 09 Jan 2008 06:05:17 CST Date: Wed, 9 Jan 2008 11:27:50 +0100 X-Kuleuven: This mail passed the K.U.Leuven mailcluster From: Dries Kimpe To: mpi-21@XXXXXXXXXXXXX Subject: Re: [mpi-21] Proposal EH2: add const keyword to the C bindings References: <6B68D01C00C9994A8E150183E62A119E6F9B5DF269@XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="1yeeQ81UyVL57Vl7" Content-Disposition: inline In-Reply-To: X-Operating-System: mhdmobile Genuine Intel(R) CPU U2500 @ 1.20GHz GNU/Linux User-Agent: Mutt/1.5.16 (2007-06-09) X-Info: Sent by mailqueue.pl X-Virus-Scanned: by KULeuven Antivirus Cluster X-Virus-Scanned: by amavisd-new-20030616-p10 (Debian) at mailbouncer.mcs.anl.gov Sender: owner-mpi-21@XXXXXXXXXXXXX Precedence: bulk Reply-To: mpi-21@XXXXXXXXXXXXX X-Virus-Scanned: by amavisd-new-20030616-p10 (Debian) at mailbouncer.mcs.anl.gov --1yeeQ81UyVL57Vl7 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline * Richard Treumann [2008-01-08 15:40:20]: > The MPI rules presumably would allow the block of code to access buf[0] and > buf[2] before and after the call to MPI_Send and the MPI_Send will not > change buf[0] or buf[2]. The practical effect of labeling buf[] const will > be correct as long as the MPI rules are followed and there is no code in > the vicinity that references buf[1]. I'm a little bit worried about the fact that const buf[] (in C) spans the whole array, while the MPI_Datatype only includes elements 0 and 2; (And even if char[] gets degraded to char * and only affects the first array element, the problem remains when switching D1 and D2 in the example below). This difference could(or could not) lead to problems, even if the user follows the MPI rules. (Assuming Richard's interpretation of the const keyword is 100% accurate) Given 2 mpi datatypes: D1: byte, 1byte-hole byte D2: 1byte-hole, byte Using these definitions, we only pass buf (and not buf[1]) to the MPI send and receive functions so: char buf[3]; 1: some_nonconst_irecv_func (buf, D1); 2: read buf[1] 3: some_const_send_func (buf, D2); 4: modify buf[1] 5: some_const_send_func (buf, D2); 6: some_complete_func (); 7: read buf[0], buf[2] Even though the user doesn't access buf[0] or buf[2] between the receive start and the receive complete, the compiler might. Assume an architecture that doesn't do non-aligned memory accesses, or one where byte access (write/read) is much slower than native-word accesses. In that case, the read on line 2 might actually read buf[0] and buf[1] into a register. In the same fashion, the modify on line 4 might write buf[0] and buf[1] (maybe even using the buf[0] value stored in a register) Even more so, since buf was only passed to const functions between line 2 and 7, the compiler might assume on line 7 that it still has the correct value of buf[0] in a register. In that case, even though the user program conforms to the MPI rules, the resulting binary would be flawed. That being said, I've done some tests and couldn't trick gcc into this behaviour. Maybe because gcc thinks it isn't slower to do byte access on the 32 bit x86 machine (which doesn't have a problem with unaligned memory access) i'm using right now, --or-- maybe because it has a rule that prohibits this behaviour. If it is the first, then we might have a problem om some architectures; If it is the second, than the const shouldn't pose a problem. As for me, I'm thinking that this is what the restrict/and or volatile keyword is for (and that the const definition given in the previous mail is too severe). Unless I'm wrong, restrict indicates that the data isn't aliased somewhere else and that the compiler can safely assume the data won't be modified by a function call that doesn't have some (non-const) reference to the data as a parameter. Except when using restrict, using a const parameter doesn't buy you anything at all except some ease of mind that a well-behaved compiler will inform you when you're trying to modify the const parameter within the function body. Besides, the fact that a function call is made using a const or nonconst parameter is a non-issue all together if one allows ``The value of buf[1] can change asynchronously any time between MPI_Irecv and MPI_Wait without any need for a function call.'' Greetings, Dries PS. I've tested using the following program: int nonconstfunc (void * b); int constfunc (const void * b); char b[4]; int main (int argc, char ** args) { b[0]=1; b[1]=2; b[2]=3; b[3]=4; nonconstfunc(b); b[0]+=1; /* cause read of B0 */ constfunc(b); b[0]=b[0]+b[2]; /* cause read of B2 */ b[0]*=2; constfunc(b); } which compiles into (gcc4, -O3, -march=prescott): movl $b, (%esp) call nonconstfunc addb $1, b movl $b, (%esp) call constfunc movzbl b+2, %eax addb b, %al movsbl %al,%eax addl %eax, %eax movb %al, b movl $b, (%esp) call constfunc --1yeeQ81UyVL57Vl7 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.7 (GNU/Linux) iD8DBQFHhKGmv/8puanD4GoRAgWxAJ9D4fLQEY7svF9O4GoSBDnA3kGN6QCbBV3u HFeAynbO/heGXJD/bkrQmeo= =gStv -----END PGP SIGNATURE----- --1yeeQ81UyVL57Vl7--