add common vector definition in ngspice code, vectorize CKTterr and BSIM3v32SIMDtrunc
This commit is contained in:
parent
47249ad57f
commit
47ae4fc706
27
configure.ac
27
configure.ac
|
|
@ -1228,6 +1228,32 @@ if test "x$enable_modsimd" = xyes; then
|
|||
])
|
||||
fi
|
||||
|
||||
# now adjust compiler flags
|
||||
if test "x$enable_modsimd" = xyes; then
|
||||
SIMD_CPPFLAGS=""
|
||||
SIMD_LDFLAGS=""
|
||||
|
||||
AC_MSG_CHECKING(whether compiler understands -fopenmp-simd)
|
||||
old_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fopenmp-simd -Werror"
|
||||
AC_TRY_COMPILE([],[], [
|
||||
AC_MSG_RESULT(yes)
|
||||
SIMD_CFLAGS="-fopenmp-simd"
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_WARN([Compiler might not understand pragma omp simd])
|
||||
SIMD_CFLAGS=""
|
||||
])
|
||||
CFLAGS="$old_CFLAGS"
|
||||
|
||||
#add -ffast-math, might need to be adjusted depending on your compiler
|
||||
SIMD_CFLAGS="$SIMD_CFLAGS -ffast-math"
|
||||
|
||||
AC_SUBST(SIMD_CPPFLAGS)
|
||||
AC_SUBST(SIMD_LDFLAGS)
|
||||
AC_SUBST(SIMD_CFLAGS)
|
||||
fi
|
||||
|
||||
if test "x$enable_modsimd" = xyes; then
|
||||
AC_DEFINE([BSIM3v32SIMD], [1], [simd acceleration for BSIM3V32 device])
|
||||
|
||||
|
|
@ -1252,6 +1278,7 @@ AC_CONFIG_FILES([Makefile
|
|||
src/Makefile
|
||||
src/spicelib/Makefile
|
||||
src/spicelib/analysis/Makefile
|
||||
src/spicelib/analysis/SIMD/Makefile
|
||||
src/spicelib/devices/Makefile
|
||||
src/spicelib/devices/asrc/Makefile
|
||||
src/spicelib/devices/bjt/Makefile
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ Xadd a1 a2 a3 a4 a1 a2 a3 a4 a1 a2 a3 a4 a1 a2 a3 a4 a1 a2 a3 a4 a1 a2 a3 a4 a1
|
|||
.save V(a1) V(a2) V(a3) V(a4) V(b1) V(b2) V(b3) V(b4)
|
||||
|
||||
* use BSIM3 model with default parameters
|
||||
.model n1 nmos level=49 version=3.2.4
|
||||
.model p1 pmos level=49 version=3.2.4
|
||||
.model n1 nmos level=49 version=3.2.4simd
|
||||
.model p1 pmos level=49 version=3.2.4simd
|
||||
*.include ./Modelcards/modelcard32.nmos
|
||||
*.include ./Modelcards/modelcard32.pmos
|
||||
|
||||
|
|
|
|||
|
|
@ -151,6 +151,11 @@ ngspice_LDADD += \
|
|||
spicelib/analysis/libckt.la \
|
||||
spicelib/devices/libdev.la
|
||||
|
||||
if WANT_MODSIMD
|
||||
ngspice_LDADD += \
|
||||
spicelib/analysis/SIMD/libcktsimd.la
|
||||
endif
|
||||
|
||||
if SENSE2_WANTED
|
||||
ngspice_LDADD += unsupported/libunsupported.la
|
||||
endif
|
||||
|
|
@ -435,6 +440,11 @@ libspice_la_LIBADD += \
|
|||
spicelib/analysis/libckt.la \
|
||||
spicelib/devices/libdev.la
|
||||
|
||||
if WANT_MODSIMD
|
||||
libspice_la_LIBADD += \
|
||||
spicelib/analysis/SIMD/libcktsimd.la
|
||||
endif
|
||||
|
||||
if XSPICE_WANTED
|
||||
libspice_la_LIBADD += \
|
||||
xspice/evt/libevtxsp.la \
|
||||
|
|
@ -555,6 +565,11 @@ libngspice_la_LIBADD += \
|
|||
spicelib/analysis/libckt.la \
|
||||
spicelib/devices/libdev.la
|
||||
|
||||
if WANT_MODSIMD
|
||||
libngspice_la_LIBADD += \
|
||||
spicelib/analysis/SIMD/libcktsimd.la
|
||||
endif
|
||||
|
||||
if XSPICE_WANTED
|
||||
libngspice_la_LIBADD += \
|
||||
xspice/evt/libevtxsp.la \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef ngspice_CKT_SIMD_H
|
||||
#define ngspice_CKT_SIMD_H
|
||||
|
||||
#include "ngspice/SIMD/simdvector.h"
|
||||
|
||||
extern void vecN_CKTterr(VecNi , CKTcircuit *, double *);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef NG_SIMD_DEF_H
|
||||
#define NG_SIMD_DEF_H
|
||||
|
||||
#define NSIMD 4
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Florian Ballenegger, Anamosic Ballenegger Design
|
||||
*******************************************************************************
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NG_SIMD_OP_H
|
||||
#define NG_SIMD_OP_H
|
||||
|
||||
#include "ngspice/SIMD/simdvector.h"
|
||||
|
||||
inline VecNd vecN_broadcast(double x)
|
||||
{
|
||||
VecNd res;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=x;
|
||||
return res;
|
||||
}
|
||||
|
||||
inline VecNd vecN_lu(double* array, VecNi indexes)
|
||||
{
|
||||
VecNd res;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=array[indexes[i]];
|
||||
return res;
|
||||
}
|
||||
|
||||
inline VecNd vecN_MAX(VecNd a, VecNd b)
|
||||
{
|
||||
VecNd res;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=(a[i] > b[i]) ? a[i] : b[i];
|
||||
return res;
|
||||
}
|
||||
|
||||
inline VecNd vecN_fabs(VecNd x)
|
||||
{
|
||||
VecNd res;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=fabs(x[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline VecNd vecN_sqrt(VecNd x)
|
||||
{
|
||||
VecNd res;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=sqrt(x[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline VecNd vecN_pow(VecNd x, double p)
|
||||
{
|
||||
VecNd res;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=log(x[i]);
|
||||
res = res*p;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=exp(res[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline VecNd vecN_exp(VecNd x)
|
||||
{
|
||||
VecNd res;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=exp(x[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline VecNd vecN_log(VecNd x)
|
||||
{
|
||||
VecNd res;
|
||||
for(int i=0;i<NSIMD;i++)
|
||||
res[i]=log(x[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef NG_SIMD_VECTOR_H
|
||||
#define NG_SIMD_VECTOR_H
|
||||
|
||||
#include "ngspice/SIMD/simddef.h"
|
||||
|
||||
#ifndef NSIMD
|
||||
#error NSIMD must be defined
|
||||
#endif
|
||||
|
||||
#if NSIMD==4
|
||||
typedef double Vec4d __attribute__ ((vector_size (sizeof(double)*4), aligned (sizeof(double)*4)));
|
||||
typedef int64_t Vec4m __attribute__ ((vector_size (sizeof(double)*4), aligned (sizeof(double)*4)));
|
||||
typedef int64_t Vec4i __attribute__ ((vector_size (sizeof(double)*4), aligned (sizeof(double)*4)));
|
||||
|
||||
#define VecNd Vec4d
|
||||
#define VecNm Vec4m
|
||||
#define VecNi Vec4i
|
||||
|
||||
#endif
|
||||
|
||||
#if NSIMD==8
|
||||
typedef double Vec8d __attribute__ ((vector_size (sizeof(double)*8), aligned (sizeof(double)*8)));
|
||||
typedef int64_t Vec8m __attribute__ ((vector_size (sizeof(double)*8), aligned (sizeof(double)*8)));
|
||||
typedef int64_t Vec8i __attribute__ ((vector_size (sizeof(double)*8), aligned (sizeof(double)*8)));
|
||||
|
||||
#define VecNd Vec8d
|
||||
#define VecNm Vec8m
|
||||
#define VecNi Vec8i
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
DIST_SUBDIRS = SIMD
|
||||
if WANT_MODSIMD
|
||||
SUBDIRS = SIMD
|
||||
endif
|
||||
|
||||
noinst_LTLIBRARIES = libckt.la
|
||||
|
||||
libckt_la_SOURCES = \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
noinst_LTLIBRARIES = libcktsimd.la
|
||||
|
||||
libcktsimd_la_SOURCES = \
|
||||
simdcktterr.c
|
||||
|
||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
|
||||
AM_CFLAGS = $(STATIC) $(SIMD_CFLAGS)
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
**********/
|
||||
/**********
|
||||
Copyright 2020 Anamosic Ballenegger Design
|
||||
Author: 2020 Florian Ballenegger
|
||||
Vector version.
|
||||
**********/
|
||||
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
#include "ngspice/SIMD/simdvector.h"
|
||||
#include "ngspice/SIMD/simdop.h"
|
||||
#include "ngspice/SIMD/simdckt.h"
|
||||
|
||||
void
|
||||
vecN_CKTterr(VecNi qcap, CKTcircuit *ckt, double *timeStep)
|
||||
{
|
||||
VecNd volttol;
|
||||
VecNd chargetol;
|
||||
VecNd tol;
|
||||
VecNd del;
|
||||
VecNd diff[8];
|
||||
double deltmp[8];
|
||||
double factor=0;
|
||||
VecNi ccap;
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
static double gearCoeff[] = {
|
||||
.5,
|
||||
.2222222222,
|
||||
.1363636364,
|
||||
.096,
|
||||
.07299270073,
|
||||
.05830903790
|
||||
};
|
||||
static double trapCoeff[] = {
|
||||
.5,
|
||||
.08333333333
|
||||
};
|
||||
ccap = qcap+1;
|
||||
|
||||
volttol = ckt->CKTabstol + ckt->CKTreltol *
|
||||
vecN_MAX( vecN_fabs(vecN_lu(ckt->CKTstate0,ccap)), vecN_fabs(vecN_lu(ckt->CKTstate1,ccap)));
|
||||
|
||||
chargetol = vecN_MAX(vecN_fabs(vecN_lu(ckt->CKTstate0,qcap)),vecN_fabs(vecN_lu(ckt->CKTstate1,qcap)));
|
||||
chargetol = ckt->CKTreltol * vecN_MAX(chargetol,vecN_broadcast(ckt->CKTchgtol))/ckt->CKTdelta;
|
||||
tol = vecN_MAX(volttol,chargetol);
|
||||
|
||||
/* now divided differences */
|
||||
for(i=ckt->CKTorder+1;i>=0;i--) {
|
||||
diff[i] = vecN_lu(ckt->CKTstates[i],qcap);
|
||||
}
|
||||
for(i=0 ; i <= ckt->CKTorder ; i++) {
|
||||
deltmp[i] = ckt->CKTdeltaOld[i];
|
||||
}
|
||||
j = ckt->CKTorder;
|
||||
for (;;) {
|
||||
for(i=0;i <= j;i++) {
|
||||
diff[i] = (diff[i] - diff[i+1])/deltmp[i];
|
||||
}
|
||||
if (--j < 0) break;
|
||||
for(i=0;i <= j;i++) {
|
||||
deltmp[i] = deltmp[i+1] + ckt->CKTdeltaOld[i];
|
||||
}
|
||||
}
|
||||
switch(ckt->CKTintegrateMethod) {
|
||||
case GEAR:
|
||||
factor = gearCoeff[ckt->CKTorder-1];
|
||||
break;
|
||||
|
||||
case TRAPEZOIDAL:
|
||||
factor = trapCoeff[ckt->CKTorder - 1] ;
|
||||
break;
|
||||
}
|
||||
del = ckt->CKTtrtol * tol/vecN_MAX(vecN_broadcast(ckt->CKTabstol),factor * vecN_fabs(diff[0]));
|
||||
if(ckt->CKTorder == 2) {
|
||||
del = vecN_sqrt(del);
|
||||
} else if (ckt->CKTorder > 2) {
|
||||
del = vecN_exp(vecN_log(del)/ckt->CKTorder);
|
||||
}
|
||||
/* now reduce with minimum */
|
||||
for(k=0;k<NSIMD;k++)
|
||||
if(del[k]<(*timeStep))
|
||||
*timeStep = del[k];
|
||||
return;
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ endif
|
|||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||
AM_CFLAGS = $(STATIC)
|
||||
if WANT_MODSIMD
|
||||
AM_CFLAGS += -fno-math-errno -ffast-math -fopenmp-simd
|
||||
AM_CFLAGS += $(SIMD_CFLAGS)
|
||||
endif
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
#define DELTA_4 0.02
|
||||
|
||||
#ifdef USE_OMP
|
||||
int BSIM3v32LoadOMP(BSIM3v32instance *here, CKTcircuit *ckt);
|
||||
void BSIM3v32LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt);
|
||||
int BSIM3v32SIMDLoadOMP(BSIM3v32instance *here, CKTcircuit *ckt);
|
||||
void BSIM3v32SIMDLoadRhsMat(GENmodel *inModel, CKTcircuit *ckt);
|
||||
#endif
|
||||
|
||||
int
|
||||
|
|
@ -49,18 +49,18 @@ BSIM3v32SIMDload (GENmodel *inModel, CKTcircuit *ckt)
|
|||
#pragma omp parallel for
|
||||
for (idx = 0; idx < model->BSIM3v32InstCount; idx++) {
|
||||
BSIM3v32instance *here = InstArray[idx];
|
||||
int local_error = BSIM3v32LoadOMP(here, ckt);
|
||||
int local_error = BSIM3v32SIMDLoadOMP(here, ckt);
|
||||
if (local_error)
|
||||
error = local_error;
|
||||
}
|
||||
|
||||
BSIM3v32LoadRhsMat(inModel, ckt);
|
||||
BSIM3v32SIMDLoadRhsMat(inModel, ckt);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int BSIM3v32LoadOMP(BSIM3v32instance *here, CKTcircuit *ckt) {
|
||||
int BSIM3v32SIMDLoadOMP(BSIM3v32instance *here, CKTcircuit *ckt) {
|
||||
BSIM3v32model *model = BSIM3v32modPtr(here);
|
||||
#else
|
||||
BSIM3v32model *model = (BSIM3v32model*)inModel;
|
||||
|
|
@ -3479,7 +3479,7 @@ return(OK);
|
|||
}
|
||||
|
||||
#ifdef USE_OMP
|
||||
void BSIM3v32LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt)
|
||||
void BSIM3v32SIMDLoadRhsMat(GENmodel *inModel, CKTcircuit *ckt)
|
||||
{
|
||||
int InstCount, idx;
|
||||
BSIM3v32instance **InstArray;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
extern int BSIM3v32LoadSeq(BSIM3v32instance *here, CKTcircuit *ckt, double* data, int stride);
|
||||
extern int BSIM3v32LoadSIMD(BSIM3v32instance **heres, CKTcircuit *ckt, double data[7][NSIMD]);
|
||||
#else
|
||||
extern void BSIM3v32LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt);
|
||||
extern void BSIM3v32SIMDLoadRhsMat(GENmodel *inModel, CKTcircuit *ckt);
|
||||
extern int BSIM3v32LoadSeq(BSIM3v32instance *here, CKTcircuit *ckt, int);
|
||||
extern int BSIM3v32LoadSIMD(BSIM3v32instance **heres, CKTcircuit *ckt);
|
||||
#endif
|
||||
|
|
@ -147,7 +147,7 @@ BSIM3v32SIMDloadSel (GENmodel *inModel, CKTcircuit *ckt)
|
|||
}
|
||||
}
|
||||
|
||||
BSIM3v32LoadRhsMat(inModel, ckt);
|
||||
BSIM3v32SIMDLoadRhsMat(inModel, ckt);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ BSIM3v32loadSelVrai (GENmodel *inModel, CKTcircuit *ckt)
|
|||
}
|
||||
if(DEBUG) printf("Now write the matrix\n");
|
||||
/* Write in matrix sequentially */
|
||||
BSIM3v32LoadRhsMat(inModel, ckt);
|
||||
BSIM3v32SIMDLoadRhsMat(inModel, ckt);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#include "ngspice/devdefs.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
#include "ngspice/SIMD/simdvector.h"
|
||||
|
||||
#if USEX86INTRINSICS==1
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,9 +28,6 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
|
||||
typedef double Vec4d __attribute__ ((vector_size (sizeof(double)*4), aligned (sizeof(double)*4)));
|
||||
typedef int64_t Vec4m __attribute__ ((vector_size (sizeof(double)*4), aligned (sizeof(double)*4)));
|
||||
|
||||
|
||||
#if USEX86INTRINSICS==1
|
||||
static inline Vec4d vec4_blend(Vec4d fa, Vec4d tr, Vec4m mask)
|
||||
|
|
|
|||
|
|
@ -28,9 +28,6 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
|
||||
typedef double Vec8d __attribute__ ((vector_size (sizeof(double)*8), aligned (sizeof(double)*8)));
|
||||
typedef int64_t Vec8m __attribute__ ((vector_size (sizeof(double)*8), aligned (sizeof(double)*8)));
|
||||
|
||||
static inline Vec8d vec8_blend(Vec8d fa, Vec8d tr, Vec8m mask)
|
||||
{
|
||||
Vec8d r;
|
||||
|
|
|
|||
|
|
@ -1211,7 +1211,7 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
}
|
||||
}
|
||||
}
|
||||
printf("BSIM3v32/SIMD has %d groups\n",ngroups);
|
||||
printf("BSIM3v32/SIMD has %d groups and %d instances total\n",ngroups, InstCount);
|
||||
if (cp_getvar("no_modsimd", CP_BOOL, NULL, 0))
|
||||
{
|
||||
printf("BSIM3v32 simd disabled at runtime\n");
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@
|
|||
#include "bsim3v32def.h"
|
||||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
#include "ngspice/SIMD/simdvector.h"
|
||||
#include "ngspice/SIMD/simdckt.h"
|
||||
#include <float.h>
|
||||
|
||||
int
|
||||
BSIM3v32SIMDtrunc (GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||
BSIM3v32SIMDtruncSeq (GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||
{
|
||||
BSIM3v32model *model = (BSIM3v32model*)inModel;
|
||||
BSIM3v32instance *here;
|
||||
|
|
@ -46,3 +48,60 @@ BSIM3v32instance *here;
|
|||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
/* omp multiprocessing is found to be counter-productive here, probably due to
|
||||
overhead, so we disable it for the BSIM3v32SIMDtrunc function */
|
||||
#undef USE_OMP
|
||||
|
||||
int
|
||||
BSIM3v32SIMDtrunc (GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||
{
|
||||
BSIM3v32model *model = (BSIM3v32model*)inModel;
|
||||
BSIM3v32instance *here;
|
||||
|
||||
#ifdef STEPDEBUG
|
||||
double debugtemp;
|
||||
#endif /* STEPDEBUG */
|
||||
int i;
|
||||
#ifndef USE_OMP
|
||||
#define TIMESTEPptr timeStep
|
||||
#else
|
||||
double reduTimeStep = *timeStep;
|
||||
#define TIMESTEPptr &locTimeStep
|
||||
#pragma omp parallel for reduction(min:reduTimeStep)
|
||||
#endif
|
||||
for(i=0;i<model->BSIM3v32InstCount;i+=NSIMD)
|
||||
{
|
||||
VecNi indexes;
|
||||
#ifdef USE_OMP
|
||||
double locTimeStep = *timeStep;
|
||||
#endif
|
||||
for(int k=0;k<NSIMD;k++)
|
||||
indexes[k] = model->BSIM3v32InstanceArray[i+k]->BSIM3v32qb;
|
||||
vecN_CKTterr(indexes,ckt,TIMESTEPptr);
|
||||
for(int k=0;k<NSIMD;k++)
|
||||
indexes[k] = model->BSIM3v32InstanceArray[i+k]->BSIM3v32qg;
|
||||
vecN_CKTterr(indexes,ckt,TIMESTEPptr);
|
||||
for(int k=0;k<NSIMD;k++)
|
||||
indexes[k] = model->BSIM3v32InstanceArray[i+k]->BSIM3v32qd;
|
||||
vecN_CKTterr(indexes,ckt,TIMESTEPptr);
|
||||
#ifdef USE_OMP
|
||||
reduTimeStep = fmin(reduTimeStep,locTimeStep);
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_OMP
|
||||
*timeStep = reduTimeStep;
|
||||
i=model->BSIM3v32InstCount & (NSIMD-1);
|
||||
#endif
|
||||
|
||||
/* less than NSIMD devices left: not worth to use openMP ? */
|
||||
for(;i<model->BSIM3v32InstCount;i++)
|
||||
{
|
||||
CKTterr(model->BSIM3v32InstanceArray[i]->BSIM3v32qb,ckt,timeStep);
|
||||
CKTterr(model->BSIM3v32InstanceArray[i]->BSIM3v32qg,ckt,timeStep);
|
||||
CKTterr(model->BSIM3v32InstanceArray[i]->BSIM3v32qd,ckt,timeStep);
|
||||
|
||||
}
|
||||
|
||||
return(OK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ File: bsim3v32def.h
|
|||
#include "ngspice/noisedef.h"
|
||||
|
||||
#ifdef BSIM3v32SIMD
|
||||
#define NSIMD 4
|
||||
#include "ngspice/SIMD/simddef.h"
|
||||
#endif
|
||||
|
||||
#define OMP_EFFMEM
|
||||
|
|
|
|||
Loading…
Reference in New Issue