From patchwork Sat Mar 8 06:38:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerry DeLisle X-Patchwork-Id: 328152 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 967382C00AD for ; Sat, 8 Mar 2014 17:39:07 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=oFiMT3ku/l6RpuCGLM9aaaOnEqXrS6z8vagZ6GLZCPY FXOjOEuK20cuWiqinVzc1h+JvpaiPHke4WZwBA9caiqnxYetpcMg3U0FYGCatZMD pFAyr1fjpZmFs2znjQLri8a2WtH/ci69bqPiLvBSDNfhp2riGsF2WM9s/ngtsCjU = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=rEgYKNk18c/bYwH4P1cX2U0pEPI=; b=Aq18TSVU06ePcAIFm t9gX6bOcNE8ZOL6QvLMIKfqhFKCtJJVtmDVcbCTUaq2jgBzsvasDg/6s0yqlWVqg YA0ygyE6JQc6sk+i0uVHtUnhuVjTE1b1kgM4uhRICTtBLD2iN62qRPeo6mKu9laV DC0BpwfWW1Qa96RNcgN5h83mGE= Received: (qmail 3740 invoked by alias); 8 Mar 2014 06:38:55 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 3720 invoked by uid 89); 8 Mar 2014 06:38:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mta41.charter.net Received: from mta41.charter.net (HELO mta41.charter.net) (216.33.127.83) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 08 Mar 2014 06:38:53 +0000 Received: from imp09 ([10.20.200.9]) by mta41.charter.net (InterMail vM.8.01.05.02 201-2260-151-103-20110920) with ESMTP id <20140308063851.FOVO21087.mta41.charter.net@imp09>; Sat, 8 Mar 2014 01:38:51 -0500 Received: from pavilion.localdomain ([68.5.43.244]) by imp09 with smtp.charter.net id aueq1n0095G55b005ueq8F; Sat, 08 Mar 2014 01:38:51 -0500 X-Authority-Analysis: v=2.0 cv=TOkd0CZa c=1 sm=1 a=mw+G4YjGptsaRR05zBLClw==:17 a=cs1xLa0W9aIA:10 a=q81ifxPFKHcA:10 a=yUnIBFQkZM0A:10 a=hOpmn2quAAAA:8 a=wIbkZNcyuuveayf0Yh4A:9 a=wPNLvfGTeEIA:10 a=35tuSjpM38A0YJ5-Vs8A:9 a=3y_qL5-EZyF07b63:21 a=4za2Ze0cUxJTLCgP:21 a=mw+G4YjGptsaRR05zBLClw==:117 X-Auth-id: anZkZWxpc2xlQGNoYXJ0ZXIubmV0 Message-ID: <531ABAF8.2070604@charter.net> Date: Fri, 07 Mar 2014 22:38:48 -0800 From: Jerry DeLisle User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: gfortran CC: gcc patches Subject: [patch, libfortran] [4.7/4.8/4.9 Regression] PR38199 missed optimization: I/O performance The attached patch addresses the problem identified in comment #22 of the PR. For character array internal unit reads, eat_spaces must call next_char to advance every single character until the end of the string is reached. In the case sited which is very contrived, this amounts to about 100000 calls to next_char. For clarity, this test case: character buffer(1)*100000 integer i,j j = 1234 write(buffer(1),'(i4)') j DO j=1,9999 ! write(*,*) buffer(1)(1:4) read(buffer,*) i ! write(*,*) i ENDDO end Without the patch takes about 25 seconds to run. With the patch this takes about 2.8 seconds. The speedup is accomplished by simply skipping over spaces without calling next_read, then backing up one character and letting the existing execution path proceed, preserving all the end of record code needed in next_char. I also remove some unneeded error checks. Regression tested on X86_64 gnu. No need for a new test case since no new functionality is added. OK for trunk? The PR is marked as a regression, so I think this could be the last piece and call it done. Regards, Jerry 2014-03-08 Jerry DeLisle PR libfortran/38199 * io/list_read.c (next_char): Delete unuseful error checks. (eat_spaces): For character array reading, skip ahead over spaces rather than call next_char multiple times. Index: list_read.c =================================================================== --- list_read.c (revision 208303) +++ list_read.c (working copy) @@ -160,7 +160,7 @@ next_char (st_parameter_dt *dtp) dtp->u.p.line_buffer_pos = 0; dtp->u.p.line_buffer_enabled = 0; - } + } /* Handle the end-of-record and end-of-file conditions for internal array unit. */ @@ -208,20 +208,8 @@ next_char (st_parameter_dt *dtp) c = cc; } - if (length < 0) - { - generate_error (&dtp->common, LIBERROR_OS, NULL); - return '\0'; - } - if (is_array_io (dtp)) { - /* Check whether we hit EOF. */ - if (length == 0) - { - generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL); - return '\0'; - } dtp->u.p.current_unit->bytes_left--; } else @@ -264,6 +252,28 @@ eat_spaces (st_parameter_dt *dtp) { int c; + /* If internal character array IO, peak ahead and seek past spaces. + This is an optimazation to eliminate numerous calls to + next character unique to character arrays with large character + lengths (PR38199). */ + if (is_array_io (dtp)) + { + gfc_offset offset = stell (dtp->u.p.current_unit->s); + gfc_offset limit = dtp->u.p.current_unit->bytes_left; + + do + { + c = dtp->internal_unit[offset++]; + dtp->u.p.current_unit->bytes_left--; + } + while (offset < limit && (c == ' ' || c == '\t')); + /* Back up, seek ahead, and fall through to complete the process + so that END conditions are handled correctly. */ + dtp->u.p.current_unit->bytes_left++; + sseek (dtp->u.p.current_unit->s, offset-1, SEEK_SET); + } + + /* Now skip spaces, EOF and EOL are handled in next_char. */ do c = next_char (dtp); while (c != EOF && (c == ' ' || c == '\t'));