Strength reduction

In compiler construction, strength reduction is a compiler optimization where expensive operations are replaced with equivalent but less expensive operations.[1] The classic example of strength reduction converts strong multiplications inside a loop into weaker additions – something that frequently occurs in array addressing.(Cooper, Simpson & Vick 1995, p. 1)

Examples of strength reduction include replacing a multiplication within a loop with an addition and replacing exponentiation within a loop with a multiplication.

Code analysis

Most of a program's execution time is typically spent in a small section of code (called a hot spot), and that code is often inside a loop that is executed over and over.

A compiler uses methods to identify loops and recognize the characteristics of register values within those loops. For strength reduction, the compiler is interested in:

  • Loop invariants: the values which do not change within the body of a loop.
  • Induction variables: the values which are being iterated each time through the loop.

Loop invariants are essentially constants within a loop, but their value may change outside of the loop. Induction variables are changing by known amounts. The terms are relative to a particular loop. When loops are nested, an induction variable in the outer loop can be a loop invariant in the inner loop.

Strength reduction looks for expressions involving a loop invariant and an induction variable. Some of those expressions can be simplified. For example, the multiplication of loop invariant c and induction variable i

c = 7;
for (i = 0; i < N; i++)
{
    y[i] = c * i;
}

can be replaced with successive weaker additions

c = 7;
k = 0;
for (i = 0; i < N; i++)
{
    y[i] = k;
    k = k + c;
}

Strength reduction example

Below is an example that will strength-reduce all the loop multiplications that arose from array indexing address calculations.

Imagine a simple loop that sets an array to the identity matrix.

for (i = 0; i < n; i++)
{
    for (j = 0; j < n; j++)
    {
        A[i,j] = 0.0;
    }
    A[i,i] = 1.0;
}

Intermediate code

The compiler will view this code as

0010  ; for (i = 0, i < n; i++)
0020  ; {
0030      r1 = #0                        ; i = 0
0040  G0000:
0050      load r2, n                     ; i < n
0060      cmp r1, r2
0070      bge G0001
0080
0090      ; for (j = 0; j < n; j++)
0100      ; {
0110           r3   = #0                 ; j = 0
0120  G0002:
0130           load r4, n                ; j < n
0140           cmp r3, r4
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0180           load r7, n
0190           r8  = r1 * r7             ; calculate subscript i * n + j
0200           r9  = r8 + r3
0210           r10 = r9 * #8             ; calculate byte address
0220           fr3 = #0.0
0230           fstore fr3, A[r10]
0240
0250           r3 = r3 + #1              ; j++
0260           br G0002
0270      ; }
0280  G0003:
0290      ; A[i,i] = 1.0;
0300      load r12, n                    ; calculate subscript i * n + i
0310      r13 = r1 * r12
0320      r14 = r13 + r1
0330      r15 = r14 * #8                 ; calculate byte address
0340      fr4 = #1.0
0350      fstore fr4, A[r15]
0360
0370      ; i++
0380      r1 = r1 + #1
0390      br G0000
0400  ; }
0410  G0001:

This expresses 2-dimensional array A as a 1-dimensional array of n*n size, so that whenever the high-level code expresses A[x, y] it will internally be A[(x*n)+y] for any given valid indices x and y.

Many optimizations

The compiler will start doing many optimizations – not just strength reduction. Expressions that are constant (invariant) within a loop will be hoisted out of the loop. Constants can be loaded outside of both loops—such as floating point registers fr3 and fr4. Recognition that some variables don't change allows registers to be merged; n is constant, so r2, r4, r7, r12 can be hoisted and collapsed. The common value i*n is computed in (the hoisted) r8 and r13, so they collapse. The innermost loop (0120-0260) has been reduced from 11 to 7 intermediate instructions. The only multiply that remains in the innermost loop is line 0210's multiply by 8.

0010  ; for (i = 0, i < n; i++)
0020    {
0030      r1 = #0                        ; i = 0
0050      load r2, n
0130 ;   load r4, n     killed; use r2
0180 ;   load r7, n     killed; use r2
0300 ;   load r12, n    killed; use r2
0220      fr3 = #0.0
0340      fr4 = #1.0
0040  G0000:
0060      cmp r1, r2                     ; i < n
0070      bge G0001
0080
0190      r8  = r1 * r2                  ; calculate subscript i * n
0310 ;   r13 = r1 * r2  killed; use r8   ; calculate subscript i * n
0090      ; for (j = 0; j < n; j++)
0100        {
0110           r3   = #0                 ; j = 0
0120  G0002:
0140           cmp r3, r2                ; j < n
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0200           r9  = r8 + r3             ; calculate subscript i * n + j
0210           r10 = r9 * #8             ; calculate byte address
0230           fstore fr3, A[r10]
0240
0250           r3 = r3 + #1              ; j++
0260           br G0002
0270        }
0280  G0003:
0290      ; A[i,i] = 1.0;
0320      r14 = r8  + r1                 ; calculate subscript i * n + i
0330      r15 = r14 * #8                 ; calculate byte address
0350      fstore fr4, A[r15]
0360
0370      ;i++
0380      r1 = r1 + #1
0390      br G0000
0400    }
0410  G0001:

There are more optimizations to do. Register r3 is the main variable in the innermost loop (0140-0260); it gets incremented by 1 each time through the loop. Register r8 (which is invariant in the innermost loop) is added to r3. Instead of using r3, the compiler can eliminate r3 and use r9. The loop, instead of being controlled by r3 = 0 to n-1, can be controlled by r9=r8+0 to r8+n-1. That adds four instructions and kills four instructions, but there's one fewer instruction inside the loop.

0110  ;       r3   = #0     killed       ; j = 0
0115           r9   = r8                 ; new assignment
0117           r20  = r8 + r2            ; new limit
0120  G0002:
0140  ;       cmp r3, r2    killed       ; j < n
0145           cmp r9, r20               ; r8 + j < r8 + n = r20
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0200  ;       r9  = r8 + r3 killed       ; calculate subscript i * n + j
0210           r10 = r9 * #8             ; calculate byte address
0230           fstore fr3, A[r10]
0240
0250  ;       r3 = r3 + #1  killed       ; j++
0255           r9 = r9 + #1              ; new loop variable
0260           br G0002

Now r9 is the loop variable, but it interacts with the multiply by 8. Here we get to do some strength reduction. The multiply by 8 can be reduced to some successive additions of 8. Now there are no multiplications inside the loop.

0115           r9   = r8                 ; new assignment
0117           r20  = r8 + r2            ; new limit
0118           r10  = r8 * #8            ; initial value of r10
0120  G0002:
0145           cmp r9, r20               ; r8 + j < r8 + n = r20
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0210  ;       r10 = r9 * #8    killed    ; calculate byte address
0230           fstore fr3, A[r10]
0240
0245           r10 = r10 + #8            ; strength reduced multiply
0255           r9 = r9 + #1              ; loop variable
0260           br G0002

Registers r9 and r10 (= 8*r9) aren't both needed; r9 can be eliminated in the loop. The loop is now 5 instructions.

0115  ;       r9   = r8         killed
0117           r20  = r8 + r2            ; limit
0118           r10  = r8 * #8            ; initial value of r10
0119           r22  = r20 * #8           ; new limit
0120  G0002:
0145  ;       cmp r9, r20       killed   ; r8 + j < r8 + n = r20
0147           cmp r10, r22              ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0230           fstore fr3, A[r10]
0240
0245           r10 = r10 + #8            ; strength reduced multiply
0255  ;       r9 = r9 + #1      killed   ; loop variable
0260           br G0002

Outer loop

Back to the whole picture:

0010  ; for (i = 0, i < n; i++)
0020    {
0030      r1 = #0                        ; i = 0
0050      load r2, n
0220      fr3 = #0.0
0340      fr4 = #1.0
0040  G0000:
0060      cmp r1, r2                     ; i < n
0070      bge G0001
0080
0190      r8   = r1 * r2                 ; calculate subscript i * n
0117      r20  = r8 + r2                 ; limit
0118      r10  = r8 * #8                 ; initial value of r10
0119      r22  = r20 * #8                ; new limit
0090      ; for (j = 0; j < n; j++)
0100        {
0120  G0002:
0147           cmp r10, r22              ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0230           fstore fr3, A[r10]
0240
0245           r10 = r10 + #8            ; strength reduced multiply
0260           br G0002
0270        }
0280  G0003:
0290      ; A[i,i] = 1.0;
0320      r14 = r8  + r1                 ; calculate subscript i * n + i
0330      r15 = r14 * #8                 ; calculate byte address
0350      fstore fr4, A[r15]
0360
0370      ;i++
0380      r1 = r1 + #1
0390      br G0000
0400    }
0410  G0001:

There are now four multiplications within the outer loop that increments r1. Register r8 = r1*r2 at 0190 can be strength reduced by setting it before entering the loop (0055) and incrementing it by r2 at the bottom of the loop (0385).

The value r8*8 (at 0118) can be strength reduced by initializing it (0056) and adding 8*r2 to it when r8 gets incremented (0386).

Register r20 is being incremented by the invariant/constant r2 each time through the loop at 0117. After being incremented, it is multiplied by 8 to create r22 at 0119. That multiplication can be strength reduced by adding 8*r2 each time through the loop.

0010  ; for (i = 0, i < n; i++)
0020    {
0030      r1 = #0                        ; i = 0
0050      load r2, n
0220      fr3 = #0.0
0340      fr4 = #1.0
0055      r8  = r1 * r2                  ; set initial value for r8
0056      r40 = r8 * #8                  ; initial value for r8 * 8
0057      r30 = r2 * #8                  ; increment for r40
0058      r20 = r8 + r2                  ; copied from 0117
0058      r22 = r20 * #8                 ; initial value of r22
0040  G0000:
0060      cmp r1, r2                     ; i < n
0070      bge G0001
0080
0190  ;  r8   = r1 * r2    killed        ; calculate subscript i * n
0117  ;  r20  = r8 + r2    killed - dead code
0118      r10  = r40                     ; strength reduced expression to r40
0119  ;  r22  = r20 * #8   killed        ; strength reduced
0090      ; for (j = 0; j < n; j++)
0100        {
0120  G0002:
0147           cmp r10, r22              ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0230           fstore fr3, A[r10]
0240
0245           r10 = r10 + #8            ; strength reduced multiply
0260           br G0002
0270        }
0280  G0003:
0290      ; A[i,i] = 1.0;
0320      r14 = r8  + r1                 ; calculate subscript i * n + i
0330      r15 = r14 * #8                 ; calculate byte address
0350      fstore fr4, A[r15]
0360
0370      ;i++
0380      r1  = r1 + #1
0385      r8  = r8 + r2                  ; strength reduce r8 = r1 * r2
0386      r40 = r40 + r30                ; strength reduce expression r8 * 8
0388      r22 = r22 + r30                ; strength reduce r22 = r20 * 8
0390      br G0000
0400    }
0410  G0001:

The last multiply

That leaves the two loops with only one multiplication operation (at 0330) within the outer loop and no multiplications within the inner loop.

0010  ; for (i = 0, i < n; i++)
0020    {
0030      r1 = #0                        ; i = 0
0050      load r2, n
0220      fr3 = #0.0
0340      fr4 = #1.0
0055      r8  = r1 * r2                  ; set initial value for r8
0056      r40 = r8 * #8                  ; initial value for r8 * 8
0057      r30 = r2 * #8                  ; increment for r40
0058      r20 = r8 + r2                  ; copied from 0117
0058      r22 = r20 * #8                 ; initial value of r22
0040  G0000:
0060      cmp r1, r2                     ; i < n
0070      bge G0001
0080
0118      r10  = r40                     ; strength reduced expression to r40
0090      ; for (j = 0; j < n; j++)
0100        {
0120  G0002:
0147           cmp r10, r22              ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0230           fstore fr3, A[r10]
0240
0245           r10 = r10 + #8            ; strength reduced multiply
0260           br G0002
0270        }
0280  G0003:
0290      ; A[i,i] = 1.0;
0320      r14 = r8  + r1                 ; calculate subscript i * n + i
0330      r15 = r14 * #8                 ; calculate byte address
0350      fstore fr4, A[r15]
0360
0370      ;i++
0380      r1  = r1 + #1
0385      r8  = r8 + r2                  ; strength reduce r8 = r1 * r2
0386      r40 = r40 + r30                ; strength reduce expression r8 * 8
0388      r22 = r22 + r30                ; strength reduce r22 = r20 * 8
0390      br G0000
0400    }
0410  G0001:

At line 0320, r14 is the sum of r8 and r1, and r8 and r1 are being incremented in the loop. Register r8 is being bumped by r2 (=n) and r1 is being bumped by 1. Consequently, r14 is being bumped by n+1 each time through the loop. The last loop multiply at 0330 can be strength reduced by adding (r2+1)*8 each time through the loop.

0010  ; for (i = 0, i < n; i++)
0020    {
0030      r1 = #0                        ; i = 0
0050      load r2, n
0220      fr3 = #0.0
0340      fr4 = #1.0
0055      r8  = r1 * r2                  ; set initial value for r8
0056      r40 = r8 * #8                  ; initial value for r8 * 8
0057      r30 = r2 * #8                  ; increment for r40
0058      r20 = r8 + r2                  ; copied from 0117
0058      r22 = r20 * #8                 ; initial value of r22
005A      r14 = r8 + r1                  ; copied from 0320
005B      r15 = r14 * #8                 ; initial value of r15 (0330)
005C      r49 = r2 + #1
005D      r50 = r49 * #8                 ; strength reduced increment
0040  G0000:
0060      cmp r1, r2                     ; i < n
0070      bge G0001
0080
0118      r10  = r40                     ; strength reduced expression to r40
0090      ; for (j = 0; j < n; j++)
0100        {
0120  G0002:
0147           cmp r10, r22              ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0230           fstore fr3, A[r10]
0240
0245           r10 = r10 + #8            ; strength reduced multiply
0260           br G0002
0270        }
0280  G0003:
0290      ; A[i,i] = 1.0;
0320  ;  r14 = r8  + r1     killed      ; dead code
0330  ;  r15 = r14 * #8     killed      ; strength reduced
0350      fstore fr4, A[r15]
0360
0370      ;i++
0380      r1  = r1 + #1
0385      r8  = r8 + r2                  ; strength reduce r8 = r1 * r2
0386      r40 = r40 + r30                ; strength reduce expression r8 * 8
0388      r22 = r22 + r30                ; strength reduce r22 = r20 * 8
0389      r15 = r15 + r50                ; strength reduce r15 = r14 * 8
0390      br G0000
0400    }
0410  G0001:

There's still more to go. Constant folding will recognize that r1=0 in the preamble, so several instructions will clean up. Register r8 isn't used in the loop, so it can disappear.

Furthermore, r1 is only being used to control the loop, so r1 can be replaced by a different induction variable such as r40. Where i went 0 <= i < n, register r40 goes 0 <= r40 < 8 * n * n.

0010  ; for (i = 0, i < n; i++)
0020    {
0030  ;  r1 = #0                        ; i = 0, becomes dead code
0050      load r2, n
0220      fr3 = #0.0
0340      fr4 = #1.0
0055  ;  r8  = #0         killed         ; r8 no longer used
0056      r40 = #0                       ; initial value for r8 * 8
0057      r30 = r2 * #8                  ; increment for r40
0058  ;  r20 = r2         killed         ; r8 = 0, becomes dead code
0058      r22 = r2  * #8                 ; r20 = r2
005A  ;  r14 =       #0   killed         ; r8 = 0, becomes dead code
005B      r15 =       #0                 ; r14 = 0
005C      r49 = r2 + #1
005D      r50 = r49 * #8                 ; strength reduced increment
005D      r60 = r2 * r30                 ; new limit for r40
0040  G0000:
0060  ;  cmp r1, r2       killed         ; i < n; induction variable replaced
0065      cmp r40, r60                   ; i * 8 * n < 8 * n * n
0070      bge G0001
0080
0118      r10  = r40                     ; strength reduced expression to r40
0090      ; for (j = 0; j < n; j++)
0100        {
0120  G0002:
0147           cmp r10, r22              ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150           bge G0003
0160
0170           ; A[i,j] = 0.0;
0230           fstore fr3, A[r10]
0240
0245           r10 = r10 + #8            ; strength reduced multiply
0260           br G0002
0270        }
0280  G0003:
0290      ; A[i,i] = 1.0;
0350      fstore fr4, A[r15]
0360
0370      ;i++
0380  ;  r1  = r1 + #1      killed       ; dead code (r40 controls loop)
0385  ;  r8  = r8 + r2      killed       ; dead code
0386      r40 = r40 + r30                ; strength reduce expression r8 * 8
0388      r22 = r22 + r30                ; strength reduce r22 = r20 * 8
0389      r15 = r15 + r50                ; strength reduce r15 = r14 * 8
0390      br G0000
0400    }
0410  G0001:

Other strength reduction operations

Operator strength reduction uses mathematical identities to replace slow math operations with faster operations. The benefits depend on the target CPU and sometimes on the surrounding code (which can affect the availability of other functional units within the CPU).

  • replacing integer division or multiplication by a power of 2 with an arithmetic shift or logical shift[2]
  • replacing integer multiplication by a constant with a combination of shifts, adds or subtracts
  • replacing integer division by a constant with a multiplication, taking advantage of the limited range of machine integers.[3] This method also works if divisor is a non-integer sufficiently greater than 1, e.g. √2 or π.[4]
Original calculation Replacement calculation
y+= 1 y++
y%2 != 0 y & 1
y = x * 2 y = x << 1
y = x / 2 y = x >> 1
y = x % 2 y = x & 1
y = x * 15 y = (x << 4) - x
y = (uint16_t)x / 10 y = ((uint32_t)x * (uint32_t)0xCCCD) >> 19)
y = (uint16_t)x / π y = (((uint32_t)x * (uint32_t)0x45F3) >> 16) + x) >> 2)

Induction variable (orphan)

Induction variable or recursive strength reduction replaces a function of some systematically changing variable with a simpler calculation using previous values of the function. In a procedural programming language this would apply to an expression involving a loop variable and in a declarative language it would apply to the argument of a recursive function.[5] For example,

 f x = ... (3 ** x) ... (f (x + 1)) ...

becomes

 f x = f' x 1
 where
   f' x z = ... z ... (f' (x + 1) (3 * z)) ...

Here modified recursive function f takes a second parameter z = 3 ** x, allowing the expensive computation (3 ** x) to be replaced by the cheaper (3 * z).

See also

Notes

  1. ^ Steven Muchnick; Muchnick and Associates (15 August 1997). Advanced Compiler Design Implementation. Morgan Kaufmann. ISBN 978-1-55860-320-2. Strength reduction.
  2. ^ In languages such as C and Java, integer division has round-towards-zero semantics, whereas a bit-shift always rounds down, requiring special treatment for negative numbers. For example, in Java, -3 / 2 evaluates to -1, whereas -3 >> 1 evaluates to -2. So in this case, the compiler cannot optimize division by two by replacing it by a bit shift.
  3. ^ Granlund, Torbjörn; Peter L. Montgomery. "Division by Invariant Integers Using Multiplication" (PDF).
  4. ^ Jones, Nigel. "Division of integers by constants". Archived from the original on 26 March 2024.
  5. ^ This article is based on material taken from Strength+reduction at the Free On-line Dictionary of Computing prior to 1 November 2008 and incorporated under the "relicensing" terms of the GFDL, version 1.3 or later.

References

Read other articles:

Chuck Grassley Charles Ernest Grassley (lahir 17 September 1933) adalah seorang politikus Amerika Serikat yang menjabat sebagai presiden pro tempore Senat Amerika Serikat Sampai 21 Januari 2021 dan digantikan oleh Patrick Leahy. Ia juga menjabat sebagai senator Amerika Serikat senior dari Iowa dan sekarang berada dalam masa jabatan ketujuhnya dalam Senat, yang mula-mula terpilih pada 1980. Bacaan tambahan Eve Fairbanks, Earnest Goes to Washington, The New Republic, September 10, 2007 Pranala ...

 

Ernst Gideon von LaudonLahir(1717-02-13)13 Februari 1717Tootzen, Livonia SwediaMeninggal14 Juli 1790(1790-07-14) (umur 73)Nový Jičín, MoraviaDikebumikanHadersdorf, WinaPengabdian Kekaisaran Rusia Kekaisaran Romawi Suci (dari 1742)Dinas/cabangTentara KekaisaranLama dinas1732–1790PangkatGeneralfeldmarschallPerang/pertempuranPerang Suksesi Polandia Pengepungan Danzig Perang Rusia-Austria-TurkiPerang Suksesi Austria Pertempuran Soor Perang Tujuh Tahun Pertempuran Domstadt...

 

статуя Ангероны во дворце Шёнбрунн в Вене. Ангеро́на (лат. Angerona или Angeronia) — в римской мифологии богиня, изображавшаяся с прижатым к губам пальцем. Её значение было неясно самим древним римлянам. Ангерону связывали с манами, таинственными силами, утешением в горе, исц...

This article relies largely or entirely on a single source. Relevant discussion may be found on the talk page. Please help improve this article by introducing citations to additional sources.Find sources: Vipakasutra – news · newspapers · books · scholar · JSTOR (February 2024) VipakasutraInformationReligionJainism Part of a series onJainism Jains History Timeline Index Philosophy Anekantavada Cosmology Ahimsa Karma Dharma Mokṣa Kevala Jnana Dravya T...

 

British industrialist and businessman For other people named Jack Walker, see Jack Walker (disambiguation). Jack WalkerJack Walker at Ewood ParkBorn(1929-05-19)19 May 1929Blackburn, Lancashire, EnglandDied17 August 2000(2000-08-17) (aged 71)St Helier, Jersey, Channel IslandsNationalityBritishOccupation(s)BusinessmanIndustrialistYears active1942–2000TitleOwner of Walkersteel(1951–1989)Owner of Blackburn Rovers F.C.(1991–2000) Jack Walker (19 May 1929 – 17 August 2000) was a B...

 

Pakistani military prep schools This is a list of cadet colleges in Pakistan. They are military high schools which prepare students for the armed forces. History In Pakistan the system of cadet colleges was introduced by the then president of Pakistan Field Marshal Ayub Khan. The first cadet college was built in Punjab in the year 1954. The initial four cadet colleges were Cadet College Hasan Abdal, Cadet College Kohat, Faujdarhat Cadet College (then East Pakistan, now in Bangladesh) and Cade...

Haze over the Southeast Asia region in mid-2019 2019 Southeast Asian hazeA NASA satellite image showing the extent of the haze in Borneo on 15 September 2019.DurationFebruary – May 2019 (Thailand)June – September 2019 (other countries)Location Brunei Indonesia Malaysia Philippines Singapore Thailand VietnamOutcomeSchool closures in Malaysia and IndonesiaCancellation of all Firefly flights between Singapore and Malaysia, as well as in IndonesiaDeathsIndon...

 

Type of furnace once used widely for smelting iron from its oxides For other uses, see Bloomery (disambiguation). This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Bloomery – news · newspapers · books · scholar · JSTOR (May 2018) (Learn how and when to remove this message) Look up bloomery in Wiktionary, the f...

 

Ketan manggaSatu porsi ketan mangga yang berisi potongan mangga dan ketanNama lainKhaoniao mamuangSajianHidangan penutupTempat asalThailandBahan utamaBeras ketan, mangga, santanSunting kotak info • L • BBantuan penggunaan templat ini  Media: Ketan manggaKetan mangga (Thai: ข้าวเหนียวมะม่วงcode: th is deprecated , RTGS: khaoniao mamuang, pengucapan [kʰâ(ː)w.nǐa̯w mā.mûa̯ŋ]) adalah hidangan penutup Thailand yang terbuat dari b...

American anthropologist (1793–1864) Henry Rowe SchoolcraftPhoto of Henry Schoolcraft in 1855BornHenry Rowe Schoolcraft(1793-03-28)March 28, 1793Guilderland, New York, U.S.DiedDecember 10, 1864(1864-12-10) (aged 71)Washington, D.C., U.S.NationalityAmericanOccupation(s)geographer, geologist, and ethnologistSpouse(s)Jane JohnstonMary HowardSignature Henry Rowe Schoolcraft (March 28, 1793 – December 10, 1864) was an American geographer, geologist, and ethnologist, noted for his early stu...

 

Un'ombra nell'ombraUna scena del filmTitolo originaleUn'ombra nell'ombra Paese di produzioneItalia Anno1979 Durata106 min Genereorrore RegiaPier Carpi SoggettoPier Carpi SceneggiaturaPier Carpi ProduttorePiero Amati Casa di produzioneRassy Film,Aretusa Film Distribuzione in italianoCinehollywood FotografiaGuglielmo Mancori MontaggioManlio Camastro Musichemusiche composte da Stelvio Cipriani, eseguite dai Goblin (Claudio Simonetti, Fabio Pignatelli, Agostino Marangolo, Massimo Morante) Scenogr...

 

2004 concert tour by Britney Spears The Onyx Hotel TourTour by Britney SpearsPromotional poster for the tourLocation Europe North America Associated albumIn the ZoneStart dateMarch 2, 2004 (2004-03-02)End dateJune 6, 2004 (2004-06-06)Legs2No. of shows54Supporting acts JC Chasez Kelis Skye Sweetnam Wicked Wisdom Attendance601,040Box office$34 million ($54.85 in 2023 dollars)[1]Britney Spears concert chronology Dream Within a Dream Tour (2001–2002) The On...

Cet article est une ébauche concernant la Belgique et le Concours Eurovision de la chanson. Vous pouvez partager vos connaissances en l’améliorant (comment ?) selon les recommandations des projets correspondants. Belgiqueau Concours Eurovision 1985 Données clés Pays  Belgique Chanson Laat me nu gaan Interprète Linda Lepomme Compositeur Pieter Verlinden (nl) Parolier Bert Vivier Langue Néerlandais Sélection nationale Radiodiffuseur Belgische Radio- en Televisieomroep (...

 

Dieser Artikel behandelt eine Zusammenschaltung von Kraftwerken zu einem System, das sich im Idealfall wie ein konventionelles Kraftwerk verhält. Zur Simulation von Kraftwerken siehe Kraftwerkssimulator. Ein virtuelles Kraftwerk aus vielen Einzelanlagen Ein virtuelles Kraftwerk ist eine Zusammenschaltung von dezentralen Stromerzeugungseinheiten, wie zum Beispiel Photovoltaikanlagen, Wasserkraftwerken, Biogas-, Windenergieanlagen, Blockheizkraftwerken sowie Batterie-Speicherkraftwerk zu eine...

 

Former kingdom in southeast Angola Mbunda KingdomReino Mbunda (Portuguese) Chiundi ca Mbunda (Mbunda)c. 1500–1917 Flag Symbol The Mbunda Kingdom's approximate area of influence (green) in 1914 on the eve of the Kolongongo War.The Mbunda Kingdom in 1700 (brown)StatusSovereign kingdom (1500–1917)CapitalLumbala N'guimboCommon languagesMbunda languagePortugueseEthnic groups Mbunda peopleReligion Christianity with some traditional practicesGovernmentAbsolute monarchy with autonomous ...

ランブルディサンプス 発祥地 スコットランド地域 スコティッシュ・ボーダーズ主な材料 ジャガイモ、キャベツ、タマネギテンプレートを表示 ランブルディサンプス(Rumbledethumps)は、スコティッシュ・ボーダーズの伝統的な料理である。主材料は、ジャガイモ、キャベツ、タマネギである。アイルランドのコルカノンやイングランドのバブル・アンド・スクイークに似�...

 

Questa voce sull'argomento centri abitati del Paraná è solo un abbozzo. Contribuisci a migliorarla secondo le convenzioni di Wikipedia. TupãssicomuneLocalizzazioneStato Brasile Stato federato Paraná MesoregioneOeste Paranaense MicroregioneToledo AmministrazioneSindacoJosé Carlos Mariussi TerritorioCoordinate24°35′14″S 53°30′44″W24°35′14″S, 53°30′44″W (Tupãssi) Altitudine540 m s.l.m. Superficie310,909 km² Abitanti7 997[1] ...

 

دومينيون سيلان دومينيون سيلانعلم دومينيون سيلانشعار   عاصمة كولمبو  نظام الحكم غير محدّد نظام الحكم ملكية دستورية  اللغة الرسمية الإنجليزية،  والسنهالية،  والتاميلية  التاريخ التأسيس 4 فبراير 1948  النهاية 22 مايو 1972  العملة روبية سريلانكية  تعديل مصد...

Bengali–Assam Gauda–Kamarupa WilayahBangladesh, India, Myanmar, NepalPenutur Rumpun bahasaIndo-Eropa Indo-IranIndo-AryaTimurBengali–Assam Bentuk awalTidak dicantumkan (Bahasa induk) Magadhi Prakrit{{{ancestor2}}}{{{ancestor3}}}{{{ancestor4}}}Bengali–Assam Kode bahasaISO 639-3–LINGUIST List beasGlottologgaud1237[1]Lokasi penuturanPeta yang menampilkan persebaran geografis dari sub-cabang rumpun bahasa Bengali–Assam menurut klasifikasi Suniti Kumar Chatterji.[2]Peta ...

 

Swedish footballer (born 1985) Andreas Granqvist Granqvist with Sweden at the 2018 FIFA World CupPersonal informationFull name Andreas Granqvist[1]Date of birth (1985-04-16) 16 April 1985 (age 39)Place of birth Påarp, SwedenHeight 1.96 m (6 ft 5 in)[1]Position(s) Centre-backYouth career0000–1999 Påarps GIF1999–2003 Helsingborgs IFSenior career*Years Team Apps (Gls)2004–2007 Helsingborgs IF 72 (1)2007 → Wigan Athletic (loan) 0 (0)2007–2008 Wigan ...