Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vLpIg-00BViv-1R for pgsql-hackers@arkaria.postgresql.org; Wed, 19 Nov 2025 21:01:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vLpIf-00FRU7-01 for pgsql-hackers@arkaria.postgresql.org; Wed, 19 Nov 2025 21:01:13 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vLpIe-00FRTz-2L for pgsql-hackers@lists.postgresql.org; Wed, 19 Nov 2025 21:01:13 +0000 Received: from mail-il1-x130.google.com ([2607:f8b0:4864:20::130]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vLpIY-000P0d-2I for pgsql-hackers@postgresql.org; Wed, 19 Nov 2025 21:01:12 +0000 Received: by mail-il1-x130.google.com with SMTP id e9e14a558f8ab-433770ba959so920405ab.1 for ; Wed, 19 Nov 2025 13:01:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763586066; x=1764190866; darn=postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=oYlWdHZic8CIPpMQ+C2A78k3y2jG4jukpUC8dHX0GDM=; b=EWXdm9nsGUPK8EF35Gbgm59t2wwCC3OiSbFOTk0D+IKEcv5iM97++nSvYbPl/ztbYI mKnEwlUBrcCElama5lMqZMa+daANSV6qLTU+q31euSpiCq63W1wOZv/CkPOoqcN3Ukhl tWb9J85+hAdXiHXKSmLc7mX78rQPh5t5HES/VOZQonaTGdBzmI0KnKzEGpyQ1QLBPvLo g411QZpxivkdEVbDxMGWUZb5RCSPv7470xfYl95vS5RDwYX+61fK5NEAZXLl1kxj+jSa unZ1tzUN7W6+P0F3h1mHditQDBnkelSGBxFxbuvgZDh9FGV9JMGWInhmu9nV+mzaanXf YpqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763586066; x=1764190866; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oYlWdHZic8CIPpMQ+C2A78k3y2jG4jukpUC8dHX0GDM=; b=rkoaYjl3lo1iAAMDxv5HmevcQtrE454ypUi0QrjF14apr4wh3dGQZcLfvEhXMKUm1R k58xLuT6QhIHdK4r5rgJV3o3UDLQqCt5StajU96Jeic/jWzOPE99ODzNsgiB6BYQHBF0 XxvEBs2FP5GAcncj3+hW21jOz5+g2p+psu1jNOuFHaUZCEIWqlLZrdoDG6FPIZjLqOcD bTMVo9HxRx2926PSFHB7TyDW0uQTbwYlLejI4t9wlU3bSZNF7VfC9e5mv0ufC6NkkXXj nSUuqQnwbzyl0a9Uy0PaJxXCoRGRs46k9TtwB5h2cddZkuTNzQdNID65NSsZrc/4m6Ly Xb5w== X-Forwarded-Encrypted: i=1; AJvYcCVrSC9B2ebmr5vTSVZoKDldvLzPVLLyrziuDyD64pYRRdZjPJkEZA78GMjPrvzxOg8L+0sCXhpfWmBA40sc@postgresql.org X-Gm-Message-State: AOJu0Yz5nypg6YcM9u+543XhhsBEP7sQI4hb7ty6iOVqv7fVKSNFU2K9 5dX4XNmt2XwBc7/qBVrIGecNObivwpc/tbSHQHmJBGR/s6/C55w1M5u8 X-Gm-Gg: ASbGnctXSJBZH6O8uTFXX+wEQMhiMxn4i6Txba4VD956KTVGt2I3DJEArBbHoHxhI58 kTle0bU/CGKlq82mhSqHgccNeo1nG9BkBrRotbEjCSUlK6osNpcADnNBSot9ffqaa/NEWJWOz6O LIpYJQDsc1oD/Mh8tIacEF6pwPAHoA5imc2IJwue2FfEHVx74YPE1yb6e5qBfYgC3B3ED/FmJXE /sEmn8GuSgGCYDiAIPipdgy2UEbjRX71YMlH1hoMGSNnroMeucjD5wgxnquR+ElNs1symBcrmT9 3XRQF1C7i7x7tfn854ncuz0RN/aPHbkkR3iWKCloIeHxQ8I21M4C9AZ32Ht9KJ9SdttJwm7/sYG 2dnCenAKSbzW+kdGjYwgmVmjxkF7Q+hQSvqTgUZ4Lda1mWhAJGugiEnzsbU72e/rYM54oj5FIQ4 sL1Z2sPYj5AK1fh5GsyaW9KlC+7mMXUNyt4i9hlBo7wzlJTJ1v1qBBgjNle92OrxFxXxSCu3FXQ Bkw X-Google-Smtp-Source: AGHT+IE6fQ0YmRBsQ6NNBL6DWEW5Mq/BBlatYRsnet9hrRRx7J0fB6QQ663sbPrrCZn3H3l737F9WA== X-Received: by 2002:a05:6e02:216b:b0:434:8ec2:9a69 with SMTP id e9e14a558f8ab-435a9074d7emr7777835ab.19.1763586065938; Wed, 19 Nov 2025 13:01:05 -0800 (PST) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 8926c6da1cb9f-5b954a44e98sm148337173.15.2025.11.19.13.01.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Nov 2025 13:01:05 -0800 (PST) Date: Wed, 19 Nov 2025 15:01:03 -0600 From: Nathan Bossart To: Nazir Bilal Yavuz Cc: Andrew Dunstan , Shinya Kato , Manni Wood , KAZAR Ayoub , PostgreSQL-development Subject: Re: Speed up COPY FROM text/CSV parsing using SIMD Message-ID: References: <5d81fbbb-7609-4445-9bc4-8af211fb7674@dunslane.net> <8e226753-57af-489a-bfbe-caa23dd71286@dunslane.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Tue, Nov 18, 2025 at 05:20:05PM +0300, Nazir Bilal Yavuz wrote: > Thanks, done. I took a look at the v3 patches. Here are my high-level thoughts: + /* + * Parse data and transfer into line_buf. To get benefit from inlining, + * call CopyReadLineText() with the constant boolean variables. + */ + if (cstate->simd_continue) + result = CopyReadLineText(cstate, is_csv, true); + else + result = CopyReadLineText(cstate, is_csv, false); I'm curious whether this actually generates different code, and if it does, if it's actually faster. We're already branching on cstate->simd_continue here. + /* Load a chunk of data into a vector register */ + vector8_load(&chunk, (const uint8 *) ©_input_buf[input_buf_ptr]); In other places, processing 2 or 4 vectors of data at a time has proven faster. Have you tried that here? + /* \n and \r are not special inside quotes */ + if (!in_quote) + match = vector8_or(vector8_eq(chunk, nl), vector8_eq(chunk, cr)); + + if (is_csv) + { + match = vector8_or(match, vector8_eq(chunk, quote)); + if (escapec != '\0') + match = vector8_or(match, vector8_eq(chunk, escape)); + } + else + match = vector8_or(match, vector8_eq(chunk, bs)); The amount of branching here catches my eye. Some branching might be unavoidable, but in general we want to keep these SIMD paths as branch-free as possible. + /* + * Found a special character. Advance up to that point and let + * the scalar code handle it. + */ + int advance = pg_rightmost_one_pos32(mask); + + input_buf_ptr += advance; + simd_total_advance += advance; Do we actually need to advance here? Or could we just fall through to the scalar path? My suspicion is that this extra code doesn't gain us much. + if (simd_last_sleep_cycle == 0) + simd_last_sleep_cycle = 1; + else if (simd_last_sleep_cycle >= SIMD_SLEEP_MAX / 2) + simd_last_sleep_cycle = SIMD_SLEEP_MAX; + else + simd_last_sleep_cycle <<= 1; + cstate->simd_current_sleep_cycle = simd_last_sleep_cycle; + cstate->simd_last_sleep_cycle = simd_last_sleep_cycle; IMHO we should be looking for ways to simplify this should-we-use-SIMD code. For example, perhaps we could just disable the SIMD path for 10K or 100K lines any time a special character is found. I'm dubious that a lot of complexity is warranted. -- nathan