i_hasser
17.10.2004, 13:16
Mal ein Auszug aus dem Memory Streaming Benchmark von AMBiX86 D:
// Full Benchmark Function Macro
// * x and y are function name and var type, b1 to b4 are function names for approp. ADD, COPY, SCALE and TRIAD Benchmark
#define MEMORY_BENCH(x,y,b1,b2,b3,b4) \
Bench_Memory1::PartResult Bench_Memory1::x(TimerF* timer_device, double runtime, int megs) \
{ \
int i,j; \
\
TIMERF_T t1,t2,t3,t4,t5; \
\
y* test_range1=new y[ ((1<<20)*megs) / sizeof(y) ]; \
y* test_range2=new y[ ((1<<20)*megs) / sizeof(y) ]; \
y* test_range3=new y[ ((1<<20)*megs) / sizeof(y) ]; \
\
int loops; \
\
for(loops=1;;loops*=2) \
{ \
t1=timer_device->getticks(); \
\
b1(test_range1, test_range2, test_range3, ((1<<20)*megs) / sizeof(y), loops); \
\
t2=timer_device->getticks(); \
if (timer_device->getseconds(t1,t2)>=(runtime/5.0)) break; \
} \
\
PartResult ret; \
\
t1=timer_device->getticks(); \
b1(test_range1, test_range2, test_range3, ((1<<20)*megs) / sizeof(y), loops); \
\
t2=timer_device->getticks(); \
b2(test_range1, test_range2, ((1<<20)*megs) / sizeof(y), loops); \
\
t3=timer_device->getticks(); \
b3(test_range1, test_range2, ((1<<20)*megs) / sizeof(y), loops); \
\
t4=timer_device->getticks(); \
b4(test_range1, test_range2, test_range3, ((1<<20)*megs) / sizeof(y), loops); \
\
t5=timer_device->getticks(); \
\
ret.ADD= ((1<<20)*megs*loops*3) / timer_device->getseconds(t1,t2); \
ret.COPY= ((1<<20)*megs*loops*2) / timer_device->getseconds(t2,t3); \
ret.SCALE=((1<<20)*megs*loops*2) / timer_device->getseconds(t3,t4); \
ret.TRIAD=((1<<20)*megs*loops*3) / timer_device->getseconds(t4,t5); \
\
delete test_range1, test_range2, test_range3; \
\
return ret; \
}
// ADD Function Macro
// * A dirty hack to save code lines ;)
// * NOTE: ubound must be a power of 2 (!)
#define MEMORY_BENCH_ADD(x,y) \
void Bench_Memory1::x (y* src1, y* src2, y* src3, int ubound, int loops) { \
int i,j; \
for(j=0;j<loops;j++) { \
for(i=0;i<ubound;i+=32) { \
src1[i+0] =src2[i+0] +src3[i+0]; src1[i+1]= src2[i+1] +src3[i+1]; \
src1[i+2] =src2[i+2] +src3[i+2]; src1[i+3]= src2[i+3] +src3[i+3]; \
src1[i+4] =src2[i+4] +src3[i+4]; src1[i+5]= src2[i+5] +src3[i+5]; \
src1[i+6] =src2[i+6] +src3[i+6]; src1[i+7]= src2[i+7] +src3[i+7]; \
src1[i+8] =src2[i+8] +src3[i+8]; src1[i+9]= src2[i+9] +src3[i+9]; \
src1[i+10] =src2[i+10] +src3[i+10]; src1[i+11]= src2[i+11] +src3[i+11]; \
src1[i+12] =src2[i+12] +src3[i+12]; src1[i+13]= src2[i+13] +src3[i+13]; \
src1[i+14] =src2[i+14] +src3[i+14]; src1[i+15]= src2[i+15] +src3[i+15]; \
src1[i+16] =src2[i+16] +src3[i+16]; src1[i+17]= src2[i+17] +src3[i+17]; \
src1[i+18] =src2[i+18] +src3[i+18]; src1[i+19]= src2[i+19] +src3[i+19]; \
src1[i+20] =src2[i+20] +src3[i+20]; src1[i+21]= src2[i+21] +src3[i+21]; \
src1[i+22] =src2[i+22] +src3[i+22]; src1[i+23]= src2[i+23] +src3[i+23]; \
src1[i+24] =src2[i+24] +src3[i+24]; src1[i+25]= src2[i+25] +src3[i+25]; \
src1[i+26] =src2[i+26] +src3[i+26]; src1[i+27]= src2[i+27] +src3[i+27]; \
src1[i+28] =src2[i+28] +src3[i+28]; src1[i+29]= src2[i+29] +src3[i+29]; \
src1[i+30] =src2[i+30] +src3[i+30]; src1[i+31]= src2[i+31] +src3[i+31]; \
} \
} \
}
// COPY Function Macro
// * A dirty hack to save code lines ;)
// * NOTE: ubound must be a power of 2 (!)
#define MEMORY_BENCH_COPY(x,y) \
void Bench_Memory1::x ( y* src1, y* src2, int ubound, int loops) { \
int i,j; \
for(j=0;j<loops;j++) { \
for(i=0;i<ubound;i+=32) { \
src1[i+0] =src2[i+0]; src1[i+1]= src2[i+1]; \
src1[i+2] =src2[i+2]; src1[i+3]= src2[i+3]; \
src1[i+4] =src2[i+4]; src1[i+5]= src2[i+5]; \
src1[i+6] =src2[i+6]; src1[i+7]= src2[i+7]; \
src1[i+8] =src2[i+8]; src1[i+9]= src2[i+9]; \
src1[i+10] =src2[i+10]; src1[i+11]= src2[i+11]; \
src1[i+12] =src2[i+12]; src1[i+13]= src2[i+13]; \
src1[i+14] =src2[i+14]; src1[i+15]= src2[i+15]; \
src1[i+16] =src2[i+16]; src1[i+17]= src2[i+17]; \
src1[i+18] =src2[i+18]; src1[i+19]= src2[i+19]; \
src1[i+20] =src2[i+20]; src1[i+21]= src2[i+21]; \
src1[i+22] =src2[i+22]; src1[i+23]= src2[i+23]; \
src1[i+24] =src2[i+24]; src1[i+25]= src2[i+25]; \
src1[i+26] =src2[i+26]; src1[i+27]= src2[i+27]; \
src1[i+28] =src2[i+28]; src1[i+29]= src2[i+29]; \
src1[i+30] =src2[i+30]; src1[i+31]= src2[i+31]; \
} \
} \
}
// SCALE Function Macro
// * A dirty hack to save code lines ;)
// * NOTE: ubound must be a power of 2 (!)
#define MEMORY_BENCH_SCALE(x,y) \
void Bench_Memory1::x ( y* src1, y* src2, int ubound, int loops) { \
int i,j; \
y a=3; \
for(j=0;j<loops;j++) { \
for(i=0;i<ubound;i+=32) { \
src1[i+0] =a*src2[i+0]; src1[i+1]= a*src2[i+1]; \
src1[i+2] =a*src2[i+2]; src1[i+3]= a*src2[i+3]; \
src1[i+4] =a*src2[i+4]; src1[i+5]= a*src2[i+5]; \
src1[i+6] =a*src2[i+6]; src1[i+7]= a*src2[i+7]; \
src1[i+8] =a*src2[i+8]; src1[i+9]= a*src2[i+9]; \
src1[i+10] =a*src2[i+10]; src1[i+11]= a*src2[i+11]; \
src1[i+12] =a*src2[i+12]; src1[i+13]= a*src2[i+13]; \
src1[i+14] =a*src2[i+14]; src1[i+15]= a*src2[i+15]; \
src1[i+16] =a*src2[i+16]; src1[i+17]= a*src2[i+17]; \
src1[i+18] =a*src2[i+18]; src1[i+19]= a*src2[i+19]; \
src1[i+20] =a*src2[i+20]; src1[i+21]= a*src2[i+21]; \
src1[i+22] =a*src2[i+22]; src1[i+23]= a*src2[i+23]; \
src1[i+24] =a*src2[i+24]; src1[i+25]= a*src2[i+25]; \
src1[i+26] =a*src2[i+26]; src1[i+27]= a*src2[i+27]; \
src1[i+28] =a*src2[i+28]; src1[i+29]= a*src2[i+29]; \
src1[i+30] =a*src2[i+30]; src1[i+31]= a*src2[i+31]; \
} \
} \
}
// TRIAD Function Macro
// * A dirty hack to save code lines ;)
// * NOTE: ubound must be a power of 2 (!)
#define MEMORY_BENCH_TRIAD(x,y) \
void Bench_Memory1::x (y* src1, y* src2, y* src3, int ubound, int loops) { \
int i,j; \
y a=3; \
for(j=0;j<loops;j++) { \
for(i=0;i<ubound;i+=32) { \
src1[i+0] =a*src2[i+0] +src3[i+0]; src1[i+1]= a*src2[i+1] +src3[i+1]; \
src1[i+2] =a*src2[i+2] +src3[i+2]; src1[i+3]= a*src2[i+3] +src3[i+3]; \
src1[i+4] =a*src2[i+4] +src3[i+4]; src1[i+5]= a*src2[i+5] +src3[i+5]; \
src1[i+6] =a*src2[i+6] +src3[i+6]; src1[i+7]= a*src2[i+7] +src3[i+7]; \
src1[i+8] =a*src2[i+8] +src3[i+8]; src1[i+9]= a*src2[i+9] +src3[i+9]; \
src1[i+10] =a*src2[i+10] +src3[i+10]; src1[i+11]= a*src2[i+11] +src3[i+11]; \
src1[i+12] =a*src2[i+12] +src3[i+12]; src1[i+13]= a*src2[i+13] +src3[i+13]; \
src1[i+14] =a*src2[i+14] +src3[i+14]; src1[i+15]= a*src2[i+15] +src3[i+15]; \
src1[i+16] =a*src2[i+16] +src3[i+16]; src1[i+17]= a*src2[i+17] +src3[i+17]; \
src1[i+18] =a*src2[i+18] +src3[i+18]; src1[i+19]= a*src2[i+19] +src3[i+19]; \
src1[i+20] =a*src2[i+20] +src3[i+20]; src1[i+21]= a*src2[i+21] +src3[i+21]; \
src1[i+22] =a*src2[i+22] +src3[i+22]; src1[i+23]= a*src2[i+23] +src3[i+23]; \
src1[i+24] =a*src2[i+24] +src3[i+24]; src1[i+25]= a*src2[i+25] +src3[i+25]; \
src1[i+26] =a*src2[i+26] +src3[i+26]; src1[i+27]= a*src2[i+27] +src3[i+27]; \
src1[i+28] =a*src2[i+28] +src3[i+28]; src1[i+29]= a*src2[i+29] +src3[i+29]; \
src1[i+30] =a*src2[i+30] +src3[i+30]; src1[i+31]= a*src2[i+31] +src3[i+31]; \
} \
} \
}
// Main Benchmark Functions
MEMORY_BENCH(bench_int8, int8, bench_int8_add, bench_int8_copy, bench_int8_scale, bench_int8_triad);
MEMORY_BENCH(bench_int16, int16, bench_int16_add, bench_int16_copy, bench_int16_scale, bench_int16_triad);
MEMORY_BENCH(bench_int32, int32, bench_int32_add, bench_int32_copy, bench_int32_scale, bench_int32_triad);
MEMORY_BENCH(bench_int64, int64, bench_int64_add, bench_int64_copy, bench_int64_scale, bench_int64_triad);
// Auxilary Benchmark functions
MEMORY_BENCH_ADD(bench_int8_add, int8);
MEMORY_BENCH_ADD(bench_int16_add, int16);
MEMORY_BENCH_ADD(bench_int32_add, int32);
MEMORY_BENCH_ADD(bench_int64_add, int64);
MEMORY_BENCH_COPY(bench_int8_copy, int8);
MEMORY_BENCH_COPY(bench_int16_copy, int16);
MEMORY_BENCH_COPY(bench_int32_copy, int32);
MEMORY_BENCH_COPY(bench_int64_copy, int64);
MEMORY_BENCH_SCALE(bench_int8_scale, int8);
MEMORY_BENCH_SCALE(bench_int16_scale, int16);
MEMORY_BENCH_SCALE(bench_int32_scale, int32);
MEMORY_BENCH_SCALE(bench_int64_scale, int64);
MEMORY_BENCH_TRIAD(bench_int8_triad, int8);
MEMORY_BENCH_TRIAD(bench_int16_triad, int16);
MEMORY_BENCH_TRIAD(bench_int32_triad, int32);
MEMORY_BENCH_TRIAD(bench_int64_triad, int64);
Gibts eigentlich auch sowas wie FOR-Schleifen für Makros? *chatt*
// Full Benchmark Function Macro
// * x and y are function name and var type, b1 to b4 are function names for approp. ADD, COPY, SCALE and TRIAD Benchmark
#define MEMORY_BENCH(x,y,b1,b2,b3,b4) \
Bench_Memory1::PartResult Bench_Memory1::x(TimerF* timer_device, double runtime, int megs) \
{ \
int i,j; \
\
TIMERF_T t1,t2,t3,t4,t5; \
\
y* test_range1=new y[ ((1<<20)*megs) / sizeof(y) ]; \
y* test_range2=new y[ ((1<<20)*megs) / sizeof(y) ]; \
y* test_range3=new y[ ((1<<20)*megs) / sizeof(y) ]; \
\
int loops; \
\
for(loops=1;;loops*=2) \
{ \
t1=timer_device->getticks(); \
\
b1(test_range1, test_range2, test_range3, ((1<<20)*megs) / sizeof(y), loops); \
\
t2=timer_device->getticks(); \
if (timer_device->getseconds(t1,t2)>=(runtime/5.0)) break; \
} \
\
PartResult ret; \
\
t1=timer_device->getticks(); \
b1(test_range1, test_range2, test_range3, ((1<<20)*megs) / sizeof(y), loops); \
\
t2=timer_device->getticks(); \
b2(test_range1, test_range2, ((1<<20)*megs) / sizeof(y), loops); \
\
t3=timer_device->getticks(); \
b3(test_range1, test_range2, ((1<<20)*megs) / sizeof(y), loops); \
\
t4=timer_device->getticks(); \
b4(test_range1, test_range2, test_range3, ((1<<20)*megs) / sizeof(y), loops); \
\
t5=timer_device->getticks(); \
\
ret.ADD= ((1<<20)*megs*loops*3) / timer_device->getseconds(t1,t2); \
ret.COPY= ((1<<20)*megs*loops*2) / timer_device->getseconds(t2,t3); \
ret.SCALE=((1<<20)*megs*loops*2) / timer_device->getseconds(t3,t4); \
ret.TRIAD=((1<<20)*megs*loops*3) / timer_device->getseconds(t4,t5); \
\
delete test_range1, test_range2, test_range3; \
\
return ret; \
}
// ADD Function Macro
// * A dirty hack to save code lines ;)
// * NOTE: ubound must be a power of 2 (!)
#define MEMORY_BENCH_ADD(x,y) \
void Bench_Memory1::x (y* src1, y* src2, y* src3, int ubound, int loops) { \
int i,j; \
for(j=0;j<loops;j++) { \
for(i=0;i<ubound;i+=32) { \
src1[i+0] =src2[i+0] +src3[i+0]; src1[i+1]= src2[i+1] +src3[i+1]; \
src1[i+2] =src2[i+2] +src3[i+2]; src1[i+3]= src2[i+3] +src3[i+3]; \
src1[i+4] =src2[i+4] +src3[i+4]; src1[i+5]= src2[i+5] +src3[i+5]; \
src1[i+6] =src2[i+6] +src3[i+6]; src1[i+7]= src2[i+7] +src3[i+7]; \
src1[i+8] =src2[i+8] +src3[i+8]; src1[i+9]= src2[i+9] +src3[i+9]; \
src1[i+10] =src2[i+10] +src3[i+10]; src1[i+11]= src2[i+11] +src3[i+11]; \
src1[i+12] =src2[i+12] +src3[i+12]; src1[i+13]= src2[i+13] +src3[i+13]; \
src1[i+14] =src2[i+14] +src3[i+14]; src1[i+15]= src2[i+15] +src3[i+15]; \
src1[i+16] =src2[i+16] +src3[i+16]; src1[i+17]= src2[i+17] +src3[i+17]; \
src1[i+18] =src2[i+18] +src3[i+18]; src1[i+19]= src2[i+19] +src3[i+19]; \
src1[i+20] =src2[i+20] +src3[i+20]; src1[i+21]= src2[i+21] +src3[i+21]; \
src1[i+22] =src2[i+22] +src3[i+22]; src1[i+23]= src2[i+23] +src3[i+23]; \
src1[i+24] =src2[i+24] +src3[i+24]; src1[i+25]= src2[i+25] +src3[i+25]; \
src1[i+26] =src2[i+26] +src3[i+26]; src1[i+27]= src2[i+27] +src3[i+27]; \
src1[i+28] =src2[i+28] +src3[i+28]; src1[i+29]= src2[i+29] +src3[i+29]; \
src1[i+30] =src2[i+30] +src3[i+30]; src1[i+31]= src2[i+31] +src3[i+31]; \
} \
} \
}
// COPY Function Macro
// * A dirty hack to save code lines ;)
// * NOTE: ubound must be a power of 2 (!)
#define MEMORY_BENCH_COPY(x,y) \
void Bench_Memory1::x ( y* src1, y* src2, int ubound, int loops) { \
int i,j; \
for(j=0;j<loops;j++) { \
for(i=0;i<ubound;i+=32) { \
src1[i+0] =src2[i+0]; src1[i+1]= src2[i+1]; \
src1[i+2] =src2[i+2]; src1[i+3]= src2[i+3]; \
src1[i+4] =src2[i+4]; src1[i+5]= src2[i+5]; \
src1[i+6] =src2[i+6]; src1[i+7]= src2[i+7]; \
src1[i+8] =src2[i+8]; src1[i+9]= src2[i+9]; \
src1[i+10] =src2[i+10]; src1[i+11]= src2[i+11]; \
src1[i+12] =src2[i+12]; src1[i+13]= src2[i+13]; \
src1[i+14] =src2[i+14]; src1[i+15]= src2[i+15]; \
src1[i+16] =src2[i+16]; src1[i+17]= src2[i+17]; \
src1[i+18] =src2[i+18]; src1[i+19]= src2[i+19]; \
src1[i+20] =src2[i+20]; src1[i+21]= src2[i+21]; \
src1[i+22] =src2[i+22]; src1[i+23]= src2[i+23]; \
src1[i+24] =src2[i+24]; src1[i+25]= src2[i+25]; \
src1[i+26] =src2[i+26]; src1[i+27]= src2[i+27]; \
src1[i+28] =src2[i+28]; src1[i+29]= src2[i+29]; \
src1[i+30] =src2[i+30]; src1[i+31]= src2[i+31]; \
} \
} \
}
// SCALE Function Macro
// * A dirty hack to save code lines ;)
// * NOTE: ubound must be a power of 2 (!)
#define MEMORY_BENCH_SCALE(x,y) \
void Bench_Memory1::x ( y* src1, y* src2, int ubound, int loops) { \
int i,j; \
y a=3; \
for(j=0;j<loops;j++) { \
for(i=0;i<ubound;i+=32) { \
src1[i+0] =a*src2[i+0]; src1[i+1]= a*src2[i+1]; \
src1[i+2] =a*src2[i+2]; src1[i+3]= a*src2[i+3]; \
src1[i+4] =a*src2[i+4]; src1[i+5]= a*src2[i+5]; \
src1[i+6] =a*src2[i+6]; src1[i+7]= a*src2[i+7]; \
src1[i+8] =a*src2[i+8]; src1[i+9]= a*src2[i+9]; \
src1[i+10] =a*src2[i+10]; src1[i+11]= a*src2[i+11]; \
src1[i+12] =a*src2[i+12]; src1[i+13]= a*src2[i+13]; \
src1[i+14] =a*src2[i+14]; src1[i+15]= a*src2[i+15]; \
src1[i+16] =a*src2[i+16]; src1[i+17]= a*src2[i+17]; \
src1[i+18] =a*src2[i+18]; src1[i+19]= a*src2[i+19]; \
src1[i+20] =a*src2[i+20]; src1[i+21]= a*src2[i+21]; \
src1[i+22] =a*src2[i+22]; src1[i+23]= a*src2[i+23]; \
src1[i+24] =a*src2[i+24]; src1[i+25]= a*src2[i+25]; \
src1[i+26] =a*src2[i+26]; src1[i+27]= a*src2[i+27]; \
src1[i+28] =a*src2[i+28]; src1[i+29]= a*src2[i+29]; \
src1[i+30] =a*src2[i+30]; src1[i+31]= a*src2[i+31]; \
} \
} \
}
// TRIAD Function Macro
// * A dirty hack to save code lines ;)
// * NOTE: ubound must be a power of 2 (!)
#define MEMORY_BENCH_TRIAD(x,y) \
void Bench_Memory1::x (y* src1, y* src2, y* src3, int ubound, int loops) { \
int i,j; \
y a=3; \
for(j=0;j<loops;j++) { \
for(i=0;i<ubound;i+=32) { \
src1[i+0] =a*src2[i+0] +src3[i+0]; src1[i+1]= a*src2[i+1] +src3[i+1]; \
src1[i+2] =a*src2[i+2] +src3[i+2]; src1[i+3]= a*src2[i+3] +src3[i+3]; \
src1[i+4] =a*src2[i+4] +src3[i+4]; src1[i+5]= a*src2[i+5] +src3[i+5]; \
src1[i+6] =a*src2[i+6] +src3[i+6]; src1[i+7]= a*src2[i+7] +src3[i+7]; \
src1[i+8] =a*src2[i+8] +src3[i+8]; src1[i+9]= a*src2[i+9] +src3[i+9]; \
src1[i+10] =a*src2[i+10] +src3[i+10]; src1[i+11]= a*src2[i+11] +src3[i+11]; \
src1[i+12] =a*src2[i+12] +src3[i+12]; src1[i+13]= a*src2[i+13] +src3[i+13]; \
src1[i+14] =a*src2[i+14] +src3[i+14]; src1[i+15]= a*src2[i+15] +src3[i+15]; \
src1[i+16] =a*src2[i+16] +src3[i+16]; src1[i+17]= a*src2[i+17] +src3[i+17]; \
src1[i+18] =a*src2[i+18] +src3[i+18]; src1[i+19]= a*src2[i+19] +src3[i+19]; \
src1[i+20] =a*src2[i+20] +src3[i+20]; src1[i+21]= a*src2[i+21] +src3[i+21]; \
src1[i+22] =a*src2[i+22] +src3[i+22]; src1[i+23]= a*src2[i+23] +src3[i+23]; \
src1[i+24] =a*src2[i+24] +src3[i+24]; src1[i+25]= a*src2[i+25] +src3[i+25]; \
src1[i+26] =a*src2[i+26] +src3[i+26]; src1[i+27]= a*src2[i+27] +src3[i+27]; \
src1[i+28] =a*src2[i+28] +src3[i+28]; src1[i+29]= a*src2[i+29] +src3[i+29]; \
src1[i+30] =a*src2[i+30] +src3[i+30]; src1[i+31]= a*src2[i+31] +src3[i+31]; \
} \
} \
}
// Main Benchmark Functions
MEMORY_BENCH(bench_int8, int8, bench_int8_add, bench_int8_copy, bench_int8_scale, bench_int8_triad);
MEMORY_BENCH(bench_int16, int16, bench_int16_add, bench_int16_copy, bench_int16_scale, bench_int16_triad);
MEMORY_BENCH(bench_int32, int32, bench_int32_add, bench_int32_copy, bench_int32_scale, bench_int32_triad);
MEMORY_BENCH(bench_int64, int64, bench_int64_add, bench_int64_copy, bench_int64_scale, bench_int64_triad);
// Auxilary Benchmark functions
MEMORY_BENCH_ADD(bench_int8_add, int8);
MEMORY_BENCH_ADD(bench_int16_add, int16);
MEMORY_BENCH_ADD(bench_int32_add, int32);
MEMORY_BENCH_ADD(bench_int64_add, int64);
MEMORY_BENCH_COPY(bench_int8_copy, int8);
MEMORY_BENCH_COPY(bench_int16_copy, int16);
MEMORY_BENCH_COPY(bench_int32_copy, int32);
MEMORY_BENCH_COPY(bench_int64_copy, int64);
MEMORY_BENCH_SCALE(bench_int8_scale, int8);
MEMORY_BENCH_SCALE(bench_int16_scale, int16);
MEMORY_BENCH_SCALE(bench_int32_scale, int32);
MEMORY_BENCH_SCALE(bench_int64_scale, int64);
MEMORY_BENCH_TRIAD(bench_int8_triad, int8);
MEMORY_BENCH_TRIAD(bench_int16_triad, int16);
MEMORY_BENCH_TRIAD(bench_int32_triad, int32);
MEMORY_BENCH_TRIAD(bench_int64_triad, int64);
Gibts eigentlich auch sowas wie FOR-Schleifen für Makros? *chatt*