рд╣рд╛рдп рд╣рдмреНрд░ред
"рдЬрд╛рджреВ рд╡рд░реНрдЧреЛрдВ" рдХрд╛ рд╡рд┐рд╖рдп рдХрд╛рдлреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдУрд░, рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╛рдЪреАрди рдХрд╛рд▓ рд╕реЗ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рджреВрд╕рд░реА рдУрд░, "рдЬрд╛рджреВ рд╡рд░реНрдЧ" рдХреА рдЧрдгрдирд╛ рдЖрдЬ рднреА рдПрдХ рдмрд╣реБрдд рд╣реА рдХрдард┐рди рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рдХрд╛рд░реНрдп рд╣реИред рдпрд╛рдж рд░рдЦреЗрдВ, "рдореИрдЬрд┐рдХ рд╕реНрдХреНрд╡рд╛рдпрд░" NxN рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕рдВрдЦреНрдпрд╛ 1..N * N рджрд░реНрдЬ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЗрд╕рдХреЗ рдХреНрд╖реИрддрд┐рдЬ, рдКрд░реНрдзреНрд╡рд╛рдзрд░ рдФрд░ рд╡рд┐рдХрд░реНрдг рдХрд╛ рдпреЛрдЧ рд╕рдорд╛рди рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛред рдпрджрд┐ рдЖрдк рдХреЗрд╡рд▓ 4x4 рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЫрд╛рдВрдЯрддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ 16 рдорд┐рд▓рддреЗ рд╣реИрдВ! = 20,922,789,888,000 рд╡рд┐рдХрд▓реНрдкред
рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдЕрдзрд┐рдХ рдХреБрд╢рд▓рддрд╛ рд╕реЗ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рдорд╕реНрдпрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рджреЛрд╣рд░рд╛рддреЗ рд╣реИрдВред рдЖрдкрдХреЛ рдПрдХ рд╡рд░реНрдЧ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╡реЗ рджреЛрд╣рд░рд╛рдПрдВ рдирд╣реАрдВ, рдФрд░ рд╕рдореЛрдЪреНрдЪ, рдКрд░реНрдзреНрд╡рд╛рдзрд░ рдФрд░ рд╡рд┐рдХрд░реНрдг рдХрд╛ рдпреЛрдЧ рд╕рдорд╛рди рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛред
рдпрд╣ рд╕рд╛рдмрд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рдпрд╣ рд░рд╛рд╢рд┐ рд╣рдореЗрд╢рд╛ рд╕рдорд╛рди рд╣реИ, рдФрд░ рдХрд┐рд╕реА рднреА n рдХреЗ рд▓рд┐рдП рд╕реВрддреНрд░ рджреНрд╡рд╛рд░рд╛ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ:

рд╣рдо 4x4 рд╡рд░реНрдЧреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдпреЛрдЧ = 34ред
рдПрдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рд╕рднреА рдЪрд░ рдХреЛ рдирдХрд╛рд░реЗрдВ, рд╣рдорд╛рд░рд╛ рд╡рд░реНрдЧ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

рдкрд╣рд▓рд╛, рдФрд░ рд╕реНрдкрд╖реНрдЯ, рд╕рдВрдкрддреНрддрд┐: рд╡рд░реНрдЧ рдХрд╛ рдпреЛрдЧ рдЬреНрдЮрд╛рдд рд╣реИ, рдЕрддреНрдпрдзрд┐рдХ рд╕реНрдЯреЛрдмрд▓реЗрдЯ рдХреЛ рд╢реЗрд╖ 3 рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
X14 = S - X11 - X12 - X13
X24 = S - X21 - X22 - X23
...
X41 = S - X11 - X21 - X31
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ 4x4 рд╡рд░реНрдЧ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ 3x3 рд╡рд░реНрдЧ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ 16 рд╕реЗ рдЦреЛрдЬ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрдо рдХрд░ рджреЗрддрд╛ рд╣реИ! 9 рддрдХ; рдпрд╛рдиреА; 57 рдорд┐рд▓рд┐рдпрди рдмрд╛рд░ред рдпрд╣ рдЬрд╛рдирддреЗ рд╣реБрдП, рд╣рдо рдХреЛрдб рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рджреЗрдЦреЗрдВ рдХрд┐ рдЖрдзреБрдирд┐рдХ рдХрдВрдкреНрдпреВрдЯрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рд╡рд┐рд╕реНрддреГрдд рдЦреЛрдЬ рдХрд┐рддрдиреА рдЬрдЯрд┐рд▓ рд╣реИред
рд╕реА ++ - рдПрдХрд▓ рдереНрд░реЗрдбреЗрдб рд╕рдВрд╕реНрдХрд░рдг
рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рд╣рдо рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рд╕реЗрдЯ 1..16 рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рд╕реЗрдЯ рдкрд░ рд▓реВрдк рдХреЗ рд▓рд┐рдП, рдпрд╣ x11 рд╣реЛрдЧрд╛ред рдлрд┐рд░ рд╣рдо рджреВрд╕рд░рд╛ рд╕реЗрдЯ рд▓реЗрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ x11 рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдкрд╣рд▓реЗ рд╕реЗ рдорд┐рд▓рдХрд░ рдмрдирддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реА рддрд░рд╣ред
рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЕрдиреБрдорд╛рдирд┐рдд рд░реВрдк рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
int squares = 0; int digits[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; Set mset(digits, digits + N*N); for (int x11 = 1; x11 <= MAX; x11++) { Set set12(mset); set12.erase(x11); for (SetIterator it12 = set12.begin(); it12 != set12.end(); it12++) { int x12 = *it12; Set set13(set12); set13.erase(x12); for (SetIterator it13 = set13.begin(); it13 != set13.end(); it13++) { int x13 = *it13; int x14 = S - x11 - x12 - x13; if (x14 < 1 || x14 > MAX) continue; if (x14 == x11 || x14 == x12 || x14 == x13) continue; ... int sh1 = x11 + x12 + x13 + x14, sh2 = x21 + x22 + x23 + x24, sh3 = x31 + x32 + x33 + x34, sh4 = x41 + x42 + x43 + x44; int sv1 = x11 + x21 + x31 + x41, sv2 = x12 + x22 + x32 + x42, sv3 = x13 + x23 + x33 + x43, sv4 = x14 + x24 + x34 + x44; int sd1 = x11 + x22 + x33 + x44, sd2 = x14 + x23 + x32 + x41; if (sh1 != S || sh2 != S || sh3 != S || sh4 != S || sv1 != S || sv2 != S || sv3 != S || sv4 != S || sd1 != S || sd2 != S) continue;
рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛ рдкреВрд░рд╛ рдЯреЗрдХреНрд╕реНрдЯ рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рдиреАрдЪреЗ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╕рдВрдкреВрд░реНрдг рд╕реНрд░реЛрдд #include <set> #include <stdio.h> #include <ctime> #include "stdafx.h" typedef std::set<int> Set; typedef Set::iterator SetIterator; #define N 4 #define MAX (N*N) #define S 34 int main(int argc, char *argv[]) { // x11 x12 x13 x14 // x21 x22 x23 x24 // x31 x32 x33 x34 // x41 x42 x43 x44 const clock_t begin_time = clock(); int squares = 0; int digits[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; Set mset(digits, digits + N*N); for (int x11 = 1; x11 <= MAX; x11++) { Set set12(mset); set12.erase(x11); for (SetIterator it12 = set12.begin(); it12 != set12.end(); it12++) { int x12 = *it12; Set set13(set12); set13.erase(x12); for (SetIterator it13 = set13.begin(); it13 != set13.end(); it13++) { int x13 = *it13; int x14 = S - x11 - x12 - x13; if (x14 < 1 || x14 > MAX) continue; if (x14 == x11 || x14 == x12 || x14 == x13) continue; Set set21(set13); set21.erase(x13); set21.erase(x14); for (SetIterator it21 = set21.begin(); it21 != set21.end(); it21++) { int x21 = *it21; Set set22(set21); set22.erase(x21); for (SetIterator it22 = set22.begin(); it22 != set22.end(); it22++) { int x22 = *it22; Set set23(set22); set23.erase(x22); for (SetIterator it23 = set23.begin(); it23 != set23.end(); it23++) { int x23 = *it23, x24 = S - x21 - x22 - x23; if (x24 < 1 || x24 > MAX) continue; if (x24 == x11 || x24 == x12 || x24 == x13 || x24 == x14 || x24 == x21 || x24 == x22 || x24 == x23) continue; Set set31(set23); set31.erase(x23); set31.erase(x24); for (SetIterator it31 = set31.begin(); it31 != set31.end(); it31++) { int x31 = *it31; Set set32(set31); set32.erase(x31); for (SetIterator it32 = set32.begin(); it32 != set32.end(); it32++) { int x32 = *it32; Set set33(set32); set33.erase(x32); for (SetIterator it33 = set33.begin(); it33 != set33.end(); it33++) { int x33 = *it33, x34 = S - x31 - x32 - x33; if (x34 < 1 || x34 > MAX) continue; if (x34 == x11 || x34 == x12 || x34 == x13 || x34 == x14 || x34 == x21 || x34 == x22 || x34 == x23 || x34 == x24 || x34 == x31 || x34 == x32 || x34 == x33) continue; int x41 = S - x11 - x21 - x31, x42 = S - x12 - x22 - x32, x43 = S - x13 - x23 - x33, x44 = S - x14 - x24 - x34; if (x41 < 1 || x41 > MAX || x42 < 1 || x42 > MAX || x43 < 1 || x43 > MAX || x44 < 1 || x41 > MAX) continue; if (x41 == x11 || x41 == x12 || x41 == x13 || x41 == x14 || x41 == x21 || x41 == x22 || x41 == x23 || x41 == x24 || x41 == x31 || x41 == x32 || x41 == x33 || x41 == x34) continue; if (x42 == x11 || x42 == x12 || x42 == x13 || x42 == x14 || x42 == x21 || x42 == x22 || x42 == x23 || x42 == x24 || x42 == x31 || x42 == x32 || x42 == x33 || x42 == x34 || x42 == x41) continue; if (x43 == x11 || x43 == x12 || x43 == x13 || x43 == x14 || x43 == x21 || x43 == x22 || x43 == x23 || x43 == x24 || x43 == x31 || x43 == x32 || x43 == x33 || x43 == x34 || x43 == x41 || x43 == x42) continue; if (x44 == x11 || x44 == x12 || x44 == x13 || x44 == x14 || x44 == x21 || x44 == x22 || x44 == x23 || x44 == x24 || x44 == x31 || x44 == x32 || x44 == x33 || x44 == x34 || x44 == x41 || x44 == x42 || x44 == x43) continue; int sh1 = x11 + x12 + x13 + x14, sh2 = x21 + x22 + x23 + x24, sh3 = x31 + x32 + x33 + x34, sh4 = x41 + x42 + x43 + x44; int sv1 = x11 + x21 + x31 + x41, sv2 = x12 + x22 + x32 + x42, sv3 = x13 + x23 + x33 + x43, sv4 = x14 + x24 + x34 + x44; int sd1 = x11 + x22 + x33 + x44, sd2 = x14 + x23 + x32 + x41; if (sh1 != S || sh2 != S || sh3 != S || sh4 != S || sv1 != S || sv2 != S || sv3 != S || sv4 != S || sd1 != S || sd2 != S) continue; printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", x11, x12, x13, x14, x21, x22, x23, x24, x31, x32, x33, x34, x41, x42, x43, x44); squares++; } } } } } } } } } printf("CNT: %d\n", squares); float diff_t = float(clock() - begin_time)/CLOCKS_PER_SEC; printf("T = %.2fs\n", diff_t); return 0; }
рдкрд░рд┐рдгрд╛рдо: рдХреБрд▓
7040 4x4 "рдореИрдЬрд┐рдХ рд╕реНрдХреНрд╡реЗрдпрд░"
рд╡рд┐рдХрд▓реНрдк рдкрд╛рдП рдЧрдП, рдФрд░ рдЦреЛрдЬ рдХрд╛ рд╕рдордп
102s рдерд╛ред

рд╡реИрд╕реЗ, рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╡рд░реНрдЧреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рд╡рд╣реА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдбрд╛рд░рд░ рдХреЗ рдЙрддреНрдХреАрд░реНрдгрди рдХреЛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдмреЗрд╢рдХ рд╡рд╣рд╛рдБ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо
рд╕рднреА 4x4 рд╡рд░реНрдЧреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:

рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдбреНрдпреВрд░рд░ рдиреЗ рдПрдХ рдХрд╛рд░рдг рдХреЗ рд▓рд┐рдП рдЫрд╡рд┐ рдореЗрдВ рдПрдХ рд╡рд░реНрдЧ рдбрд╛рд▓рд╛, рд╕рдВрдЦреНрдпрд╛
1514 рднреА рдЙрддреНрдХреАрд░реНрдгрди рдХреЗ рд╡рд░реНрд╖ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддреА рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ (рд╣рдо 1514 рдореЗрдВ рдЕрд▓реНрдмреНрд░реЗрдХреНрдЯ рдбреНрдпреВрд░рд░ рджреНрд╡рд╛рд░рд╛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд╛рд░реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реИрдВ;), рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреЛрд░ i7 рдкреНрд░реЛрд╕реЗрд╕рд░ рд╡рд╛рд▓реЗ рдХрдВрдкреНрдпреВрдЯрд░ рдХреЗ рд▓рд┐рдП рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдЗрддрдирд╛ рдЫреЛрдЯрд╛ рдирд╣реАрдВ рд╣реИред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдХрд╛рд░реНрдпрдХреНрд░рдо рдПрдХ рд╣реА рдзрд╛рдЧреЗ рдореЗрдВ рдЪрд▓рддрд╛ рд╣реИ, рдФрд░ рдЕрдиреНрдп рд╕рднреА рдЧреБрдард▓реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЙрдЪрд┐рдд рд╣реИред
рд╕реА ++ - рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╕рдВрд╕реНрдХрд░рдг
рдзрд╛рд░рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдореВрд▓ рд░реВрдк рд╕реЗ рд╕реАрдзрд╛ рд╣реИ, рдереЛрдбрд╝рд╛ рдмреЛрдЭрд┐рд▓ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд╡рдЬреВрджред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЖрдЬ рдПрдХ рд▓рдЧрднрдЧ рднреВрд▓ рдЧрдпрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реИ -
рдУрдкрдирдПрдордкреА (рдУрдкрди рдорд▓реНрдЯреА-рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ) рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХрд╛ рдЙрдкрдпреЛрдЧред рдпрд╣ рддрдХрдиреАрдХ 1998 рд╕реЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдореЗрдВ рд╣реИ, рдФрд░ рдкреНрд░реЛрд╕реЗрд╕рд░ рдирд┐рд░реНрджреЗрд╢рдХреЛрдВ рдХреЛ рд╕рдВрдХрд▓рдХ рдХреЛ рдпрд╣ рдмрддрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдХрд┐рди рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рдПред OpenMP рднреА Visual Studio рдореЗрдВ рд╕рдорд░реНрдерд┐рдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХрд┐рд╕реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреЛрдб рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝реЗрдВ:
int squares = 0; #pragma omp parallel for reduction(+: squares) for (int x11 = 1; x11 <= MAX; x11++) { ... } printf("CNT: %d\n", squares);
рдирд┐рд░реНрджреЗрд╢ #pragma omp рд╕рдорд╛рдирд╛рдВрддрд░ рдХреЗ рд▓рд┐рдП рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд▓реВрдк рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓рд╛ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд░реНрдЧ рдЪрд░ рдирд╛рдо рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╕рдорд╛рдирд╛рдВрддрд░ рдереНрд░реЗрдбреНрд╕ рдХреЗ рд▓рд┐рдП рдЖрдо рд╣реЛрдЧрд╛ (рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рд╡реЗрддрди рд╡реГрджреНрдзрд┐ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИ)ред
рдкрд░рд┐рдгрд╛рдо рд╕реНрдкрд╖реНрдЯ рд╣реИ: рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рд╕рдордп 102s рд╕реЗ рдШрдЯрд╛рдХрд░
18s рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рд╕рдВрдкреВрд░реНрдг рд╕реНрд░реЛрдд #include <set> #include <stdio.h> #include <ctime> #include "stdafx.h" typedef std::set<int> Set; typedef Set::iterator SetIterator; #define N 4 #define MAX (N*N) #define S 34 int main(int argc, char *argv[]) { // x11 x12 x13 x14 // x21 x22 x23 x24 // x31 x32 x33 x34 // x41 x42 x43 x44 const clock_t begin_time = clock(); int squares = 0; #pragma omp parallel for reduction(+: squares) for (int x11 = 1; x11 <= MAX; x11++) { int digits[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; Set mset(digits, digits + N*N); Set set12(mset); set12.erase(x11); for (SetIterator it12 = set12.begin(); it12 != set12.end(); it12++) { int x12 = *it12; Set set13(set12); set13.erase(x12); for (SetIterator it13 = set13.begin(); it13 != set13.end(); it13++) { int x13 = *it13; int x14 = S - x11 - x12 - x13; if (x14 < 1 || x14 > MAX) continue; if (x14 == x11 || x14 == x12 || x14 == x13) continue; Set set21(set13); set21.erase(x13); set21.erase(x14); for (SetIterator it21 = set21.begin(); it21 != set21.end(); it21++) { int x21 = *it21; Set set22(set21); set22.erase(x21); for (SetIterator it22 = set22.begin(); it22 != set22.end(); it22++) { int x22 = *it22; Set set23(set22); set23.erase(x22); for (SetIterator it23 = set23.begin(); it23 != set23.end(); it23++) { int x23 = *it23, x24 = S - x21 - x22 - x23; if (x24 < 1 || x24 > MAX) continue; if (x24 == x11 || x24 == x12 || x24 == x13 || x24 == x14 || x24 == x21 || x24 == x22 || x24 == x23) continue; Set set31(set23); set31.erase(x23); set31.erase(x24); for (SetIterator it31 = set31.begin(); it31 != set31.end(); it31++) { int x31 = *it31; Set set32(set31); set32.erase(x31); for (SetIterator it32 = set32.begin(); it32 != set32.end(); it32++) { int x32 = *it32; Set set33(set32); set33.erase(x32); for (SetIterator it33 = set33.begin(); it33 != set33.end(); it33++) { int x33 = *it33, x34 = S - x31 - x32 - x33; if (x34 < 1 || x34 > MAX) continue; if (x34 == x11 || x34 == x12 || x34 == x13 || x34 == x14 || x34 == x21 || x34 == x22 || x34 == x23 || x34 == x24 || x34 == x31 || x34 == x32 || x34 == x33) continue; int x41 = S - x11 - x21 - x31, x42 = S - x12 - x22 - x32, x43 = S - x13 - x23 - x33, x44 = S - x14 - x24 - x34; if (x41 < 1 || x41 > MAX || x42 < 1 || x42 > MAX || x43 < 1 || x43 > MAX || x44 < 1 || x41 > MAX) continue; if (x41 == x11 || x41 == x12 || x41 == x13 || x41 == x14 || x41 == x21 || x41 == x22 || x41 == x23 || x41 == x24 || x41 == x31 || x41 == x32 || x41 == x33 || x41 == x34) continue; if (x42 == x11 || x42 == x12 || x42 == x13 || x42 == x14 || x42 == x21 || x42 == x22 || x42 == x23 || x42 == x24 || x42 == x31 || x42 == x32 || x42 == x33 || x42 == x34 || x42 == x41) continue; if (x43 == x11 || x43 == x12 || x43 == x13 || x43 == x14 || x43 == x21 || x43 == x22 || x43 == x23 || x43 == x24 || x43 == x31 || x43 == x32 || x43 == x33 || x43 == x34 || x43 == x41 || x43 == x42) continue; if (x44 == x11 || x44 == x12 || x44 == x13 || x44 == x14 || x44 == x21 || x44 == x22 || x44 == x23 || x44 == x24 || x44 == x31 || x44 == x32 || x44 == x33 || x44 == x34 || x44 == x41 || x44 == x42 || x44 == x43) continue; int sh1 = x11 + x12 + x13 + x14, sh2 = x21 + x22 + x23 + x24, sh3 = x31 + x32 + x33 + x34, sh4 = x41 + x42 + x43 + x44; int sv1 = x11 + x21 + x31 + x41, sv2 = x12 + x22 + x32 + x42, sv3 = x13 + x23 + x33 + x43, sv4 = x14 + x24 + x34 + x44; int sd1 = x11 + x22 + x33 + x44, sd2 = x14 + x23 + x32 + x41; if (sh1 != S || sh2 != S || sh3 != S || sh4 != S || sv1 != S || sv2 != S || sv3 != S || sv4 != S || sd1 != S || sd2 != S) continue; printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", x11, x12, x13, x14, x21, x22, x23, x24, x31, x32, x33, x34, x41, x42, x43, x44); squares++; } } } } } } } } } printf("CNT: %d\n", squares); float diff_t = float(clock() - begin_time)/CLOCKS_PER_SEC; printf("T = %.2fs\n", diff_t); return 0; }
рдпрд╣ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд╣реИ - рдХреНрдпреЛрдВрдХрд┐ рдХрд╛рд░реНрдп рд▓рдЧрднрдЧ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдорд╛рдирд╛рдВрддрд░ рд╣реИ (рдкреНрд░рддреНрдпреЗрдХ рд╢рд╛рдЦрд╛ рдореЗрдВ рдЧрдгрдирд╛ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИрдВ), рд╕рдордп рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛрд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╕рдордп рд╕реЗ рдХрдо рд╣реИред рд▓реЗрдХрд┐рди рдЕрдлрд╕реЛрд╕, рдЗрд╕ рдХреЛрдб рд╕реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХреБрдЫ рдкреНрд░рддрд┐рд╢рдд рдФрд░ рдХреБрдЫ рдЕрдиреБрдХреВрд▓рди рджреНрд╡рд╛рд░рд╛ рдЬреАрддрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо GPU рдкрд░ рднрд╛рд░реА рддреЛрдкрдЦрд╛рдиреЗ, рдЧрдгрдирд╛рдУрдВ рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
NVIDIA CUDA рдХреЗ рд╕рд╛рде рдХрдореНрдкреНрдпреВрдЯрд┐рдВрдЧ
рдпрджрд┐ рдЖрдк рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдкрд░ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдЧрдгрдирд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдХрдИ рд╕рдорд╛рдирд╛рдВрддрд░ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдмреНрд▓реЙрдХреЛрдВ (рдмреНрд▓реЙрдХ) рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ (рдереНрд░реЗрдбреНрд╕) рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо CUDA рдкреНрд░рд▓реЗрдЦрди рд╕реЗ 2 рд╡реИрдХреНрдЯрд░ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗ рд╕рдХрддреЗ рд╣реИрдВ:
__global__ void add(int n, float *x, float *y) { int index = threadIdx.x; int stride = blockDim.x; for (int i = index; i < n; i += stride) y[i] = x[i] + y[i]; }
рдПрдХреНрд╕ рдФрд░ рд╡рд╛рдИ рд╕рднреА рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рд╣реИрдВ, рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╕рд╛рде рдХрдИ рдкреНрд░реЛрд╕реЗрд╕рд░ рдкрд░ рдПрдХ рд╕рд╛рде рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдХреБрдВрдЬреА рд╕рдорд╛рдирддрд╛ рд╣реИ - рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдкреНрд░реЛрд╕реЗрд╕рд░ рдПрдХ рдирд┐рдпрдорд┐рдд рд╕реАрдкреАрдпреВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рд╕реЗ рдХрдИ рд╣реИрдВ рдФрд░ рд╡реЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдбреЗрдЯрд╛ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИрдВред
рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдПред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ X11, X12, .., X44 рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдПрдХ рдореИрдЯреНрд░рд┐рдХреНрд╕ рд╣реИред рдЪрд▓реЛ 16 рдмреНрд▓реЙрдХреЛрдВ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ 16 рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛ред рдмреНрд▓реЙрдХ рд╕рдВрдЦреНрдпрд╛ X11, рд╕рдВрдЦреНрдпрд╛ X12 рдХреЗ рд▓рд┐рдП рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдЧреА, рдФрд░ рдХреЛрдб рд╕реНрд╡рдпрдВ рдЪрдпрдирд┐рдд X11 рдФрд░ X12 рдХреЗ рд▓рд┐рдП рд╕рднреА рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд░реНрдЧреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдЧрд╛ред рдпрд╣ рд╕рд░рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╕реВрдХреНрд╖реНрдорддрд╛ рд╣реИ - рдбреЗрдЯрд╛ рдХреЛ рди рдХреЗрд╡рд▓ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдмреИрдХ рд╕реЗ рднреА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рд╕рд░рдгреА рдХреЗ рд╢реВрдиреНрдп рддрддреНрд╡ рдореЗрдВ рдкрд╛рдП рдЧрдП рд╡рд░реНрдЧреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗред
рдореБрдЦреНрдп рдХреЛрдб рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ:
#define N 4 #define SQ_MAX 8*1024 #define BLOCK_SIZE (SQ_MAX*N*N + 1) int main(int argc,char *argv[]) { const clock_t begin_time = clock(); int *results = (int*)malloc(BLOCK_SIZE*sizeof(int)); results[0] = 0; int *gpu_out = NULL; cudaMalloc(&gpu_out, BLOCK_SIZE*sizeof(int)); cudaMemcpy(gpu_out, results, BLOCK_SIZE*sizeof(int), cudaMemcpyHostToDevice); squares<<<MAX, MAX>>>(gpu_out); cudaMemcpy(results, gpu_out, BLOCK_SIZE*sizeof(int), cudaMemcpyDeviceToHost); // Print results int squares = results[0]; for(int p=0; p<SQ_MAX && p<squares; p++) { int i = MAX*p + 1; printf("[%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d]\n", results[i], results[i+1], results[i+2], results[i+3], results[i+4], results[i+5], results[i+6], results[i+7], results[i+8], results[i+9], results[i+10], results[i+11], results[i+12], results[i+13], results[i+14], results[i+15]); } printf ("CNT: %d\n", squares); float diff_t = float(clock() - begin_time)/CLOCKS_PER_SEC; printf("T = %.2fs\n", diff_t); cudaFree(gpu_out); free(results); return 0; }
рд╣рдо cudaMalloc рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдкрд░ рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХ рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ, рд╡рд░реНрдЧреЛрдВ рдХреЛ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, 2 рдкреИрд░рд╛рдореАрдЯрд░ 16.16 (рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛) рдХреЛ рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВ, рдЬреЛ рд╕рдВрдЦреНрдпрд╛ 1..16 рд╕реЗ рдЕрдзрд┐рдХ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВ, рдлрд┐рд░ рдбреЗрдЯрд╛ рдХреЛ cudaMemcpy рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд╛рдкрд╕ рдХреЙрдкреА рдХрд░реЗрдВред
рд╕реНрдХреНрд╡рд╛рдпрд░ рдлрд╝рдВрдХреНрд╢рди рд╕реНрд╡рдпрдВ рдХреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдкрд┐рдЫрд▓реЗ рднрд╛рдЧ рд╕реЗ рдХреЛрдб рдХреЛ рджреЛрд╣рд░рд╛рддрд╛ рд╣реИ, рдЗрд╕ рдЕрдВрддрд░ рдХреЗ рд╕рд╛рде рдХрд┐ рдкрд╛рдпрд╛ рдЧрдпрд╛ рдХрд┐ рд╡рд░реНрдЧреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдкрд░рдорд╛рдгреБ-рдЖрдпреБрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреА рдЬрд╛рддреА рд╣реИ - рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЪрд░ рдПрдХ рд╕рд╛рде рдХреЙрд▓ рдХреЗ рджреМрд░рд╛рди рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред
рд╕рдВрдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ - рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рд╕рдордп
2.7 s рдерд╛, рдЬреЛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд▓рдЧрднрдЧ 30 рдЧреБрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ:

рдЬреИрд╕рд╛ рдХрд┐ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЖрдк рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдХреЗ рдФрд░ рднреА рдЕрдзрд┐рдХ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдмреНрд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП 256 рдмреНрд▓реЙрдХреЛрдВ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рдЖрдЬрд╝рдорд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдХреЛрдб рдмрджрд▓рдирд╛ рдиреНрдпреВрдирддрдо рд╣реИ:
__global__ void squares(int *res_array) { int index1 = blockIdx.x/MAX, index2 = blockIdx.x%MAX; ... } squares<<<MAX*MAX, 1>>>(gpu_out);
рдЗрд╕рдиреЗ рд╕рдордп рдХреЛ 2 рдЧреБрдирд╛ рдШрдЯрд╛рдХрд░
1.2s рдХрд░ рджрд┐рдпрд╛ ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рдмреНрд▓реЙрдХ рдкрд░ 16 рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рд╢реБрд░реВ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВ, рдЬреЛ
0.44 рдХрд╛ рд╕рд░реНрд╡реЛрддреНрддрдо рд╕рдордп
рджреЗрддреА рд╣реИрдВ ред
рдЕрдВрддрд┐рдо рдХреЛрдб #include <stdio.h> #include <ctime> #define N 4 #define MAX (N*N) #define SQ_MAX 8*1024 #define BLOCK_SIZE (SQ_MAX*N*N + 1) #define S 34 // Magic square: // x11 x12 x13 x14 // x21 x22 x23 x24 // x31 x32 x33 x34 // x41 x42 x43 x44 __global__ void squares(int *res_array) { int index1 = blockIdx.x/MAX, index2 = blockIdx.x%MAX, index3 = threadIdx.x; if (index1 + 1 > MAX || index2 + 1 > MAX || index3 + 1 > MAX) return; const int x11 = index1+1, x12 = index2+1, x13 = index3+1; if (x13 == x11 || x13 == x12) return; int x14 = S - x11 - x12 - x13; if (x14 < 1 || x14 > MAX) return; if (x14 == x11 || x14 == x12 || x14 == x13) return; for(int x21=1; x21<=MAX; x21++) { if (x21 == x11 || x21 == x12 || x21 == x13 || x21 == x14) continue; for(int x22=1; x22<=MAX; x22++) { if (x22 == x11 || x22 == x12 || x22 == x13 || x22 == x14 || x22 == x21) continue; for(int x23=1; x23<=MAX; x23++) { int x24 = S - x21 - x22 - x23; if (x24 < 1 || x24 > MAX) continue; if (x23 == x11 || x23 == x12 || x23 == x13 || x23 == x14 || x23 == x21 || x23 == x22) continue; if (x24 == x11 || x24 == x12 || x24 == x13 || x24 == x14 || x24 == x21 || x24 == x22 || x24 == x23) continue; for(int x31=1; x31<=MAX; x31++) { if (x31 == x11 || x31 == x12 || x31 == x13 || x31 == x14 || x31 == x21 || x31 == x22 || x31 == x23 || x31 == x24) continue; for(int x32=1; x32<=MAX; x32++) { if (x32 == x11 || x32 == x12 || x32 == x13 || x32 == x14 || x32 == x21 || x32 == x22 || x32 == x23 || x32 == x24 || x32 == x31) continue; for(int x33=1; x33<=MAX; x33++) { int x34 = S - x31 - x32 - x33; if (x34 < 1 || x34 > MAX) continue; if (x33 == x11 || x33 == x12 || x33 == x13 || x33 == x14 || x33 == x21 || x33 == x22 || x33 == x23 || x33 == x24 || x33 == x31 || x33 == x32) continue; if (x34 == x11 || x34 == x12 || x34 == x13 || x34 == x14 || x34 == x21 || x34 == x22 || x34 == x23 || x34 == x24 || x34 == x31 || x34 == x32 || x34 == x33) continue; const int x41 = S - x11 - x21 - x31, x42 = S - x12 - x22 - x32, x43 = S - x13 - x23 - x33, x44 = S - x14 - x24 - x34; if (x41 < 1 || x41 > MAX || x42 < 1 || x42 > MAX || x43 < 1 || x43 > MAX || x44 < 1 || x44 > MAX) continue; if (x41 == x11 || x41 == x12 || x41 == x13 || x41 == x14 || x41 == x21 || x41 == x22 || x41 == x23 || x41 == x24 || x41 == x31 || x41 == x32 || x41 == x33 || x41 == x34) continue; if (x42 == x11 || x42 == x12 || x42 == x13 || x42 == x14 || x42 == x21 || x42 == x22 || x42 == x23 || x42 == x24 || x42 == x31 || x42 == x32 || x42 == x33 || x42 == x34 || x42 == x41) continue; if (x43 == x11 || x43 == x12 || x43 == x13 || x43 == x14 || x43 == x21 || x43 == x22 || x43 == x23 || x43 == x24 || x43 == x31 || x43 == x32 || x43 == x33 || x43 == x34 || x43 == x41 || x43 == x42) continue; if (x44 == x11 || x44 == x12 || x44 == x13 || x44 == x14 || x44 == x21 || x44 == x22 || x44 == x23 || x44 == x24 || x44 == x31 || x44 == x32 || x44 == x33 || x44 == x34 || x44 == x41 || x44 == x42 || x44 == x43) continue; int sh1 = x11 + x12 + x13 + x14, sh2 = x21 + x22 + x23 + x24, sh3 = x31 + x32 + x33 + x34, sh4 = x41 + x42 + x43 + x44; int sv1 = x11 + x21 + x31 + x41, sv2 = x12 + x22 + x32 + x42, sv3 = x13 + x23 + x33 + x43, sv4 = x14 + x24 + x34 + x44; int sd1 = x11 + x22 + x33 + x44, sd2 = x14 + x23 + x32 + x41; if (sh1 != S || sh2 != S || sh3 != S || sh4 != S || sv1 != S || sv2 != S || sv3 != S || sv4 != S || sd1 != S || sd2 != S) continue; // Square found: save in array (MAX numbers for each square) int p = atomicAdd(res_array, 1); if (p >= SQ_MAX) continue; int i = MAX*p + 1; res_array[i] = x11; res_array[i+1] = x12; res_array[i+2] = x13; res_array[i+3] = x14; res_array[i+4] = x21; res_array[i+5] = x22; res_array[i+6] = x23; res_array[i+7] = x24; res_array[i+8] = x31; res_array[i+9] = x32; res_array[i+10] = x33; res_array[i+11] = x34; res_array[i+12]= x41; res_array[i+13]= x42; res_array[i+14] = x43; res_array[i+15] = x44; // Warning: printf from kernel makes calculation 2-3x slower // printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", x11, x12, x13, x14, x21, x22, x23, x24, x31, x32, x33, x34, x41, x42, x43, x44); } } } } } } } int main(int argc,char *argv[]) { int *gpu_out = NULL; cudaMalloc(&gpu_out, BLOCK_SIZE*sizeof(int)); const clock_t begin_time = clock(); int *results = (int*)malloc(BLOCK_SIZE*sizeof(int)); results[0] = 0; cudaMemcpy(gpu_out, results, BLOCK_SIZE*sizeof(int), cudaMemcpyHostToDevice); squares<<<MAX*MAX, MAX>>>(gpu_out); cudaMemcpy(results, gpu_out, BLOCK_SIZE*sizeof(int), cudaMemcpyDeviceToHost); // Print results int squares = results[0]; for(int p=0; p<SQ_MAX && p<squares; p++) { int i = MAX*p + 1; printf("[%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d]\n", results[i], results[i+1], results[i+2], results[i+3], results[i+4], results[i+5], results[i+6], results[i+7], results[i+8], results[i+9], results[i+10], results[i+11], results[i+12], results[i+13], results[i+14], results[i+15]); } printf ("CNT: %d\n", squares); float diff_t = float(clock() - begin_time)/CLOCKS_PER_SEC; printf("T = %.2fs\n", diff_t); cudaFree(gpu_out); free(results); return 0; }
рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рдпрд╣ рдЖрджрд░реНрд╢ рд╕реЗ рдмрд╣реБрдд рджреВрд░ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЬреАрдкреАрдпреВ рдкрд░ рдФрд░ рднреА рдЕрдзрд┐рдХ рдмреНрд▓реЙрдХ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рднреНрд░рдорд┐рдд рдФрд░ рд╕рдордЭрдиреЗ рдореЗрдВ рдореБрд╢реНрдХрд┐рд▓ рдмрдирд╛ рджреЗрдЧрд╛ред рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЧрдгрдирд╛ "рдореБрдХреНрдд" рдирд╣реАрдВ рд╣реИрдВ - рдЬрдм рдЬреАрдкреАрдпреВ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╡рд┐рдВрдбреЛрдЬ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛рдлрд╝реА рдзреАрдорд╛ рд╣реЛрдиреЗ рд▓рдЧрддрд╛ рд╣реИ, рдФрд░ рдХрдВрдкреНрдпреВрдЯрд░ рдХреА рдмрд┐рдЬрд▓реА рдХреА рдЦрдкрдд рд▓рдЧрднрдЧ 2 рдЧреБрдирд╛ рдмрдврд╝ рдЬрд╛рддреА рд╣реИ, 65 рд╕реЗ 130W рддрдХред
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ : рдЬреИрд╕рд╛ рдХрд┐
Bodigrim рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рд╣реИ, рдПрдХ рдФрд░ рд╕рдорд╛рдирддрд╛ 4x4 рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рд░рдЦрддреА рд╣реИ: 4 "рдЖрдВрддрд░рд┐рдХ" рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХрд╛ рдпреЛрдЧ "рдмрд╛рд╣рд░реА" рд▓реЛрдЧреЛрдВ рдХреЗ рдпреЛрдЧ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рдпрд╣ рднреА рдПрд╕ред

X22 + X23 + X32 + X33 = X11 + X41 + X14 + X44 = S
рдпрд╣ рджреВрд╕рд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреБрдЫ рдЪрд░ рдХреЛ рд╡реНрдпрдХреНрдд рдХрд░рдХреЗ рдФрд░ рдПрдХ рдФрд░ 1-2 рдиреЗрд╕реНрдЯреЗрдб рдЫреЛрд░реЛрдВ рдХреЛ рд╣рдЯрд╛рдХрд░ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдФрд░ рдЧрддрд┐ рджреЗрдЧрд╛, рдХреЛрдб рдХрд╛ рдПрдХ рдЕрджреНрдпрддрди рд╕рдВрд╕реНрдХрд░рдг рдиреАрдЪреЗ рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредрдирд┐рд╖реНрдХрд░реНрд╖
"рдЬрд╛рджреБрдИ рд╡рд░реНрдЧ" рдЦреЛрдЬрдиреЗ рдХрд╛ рдХрд╛рдо рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдФрд░ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ GPU рдкрд░ рдЧрдгрдирд╛ рдХреЗ рд╕рд╛рде, рд╕рднреА 5x5 рд╡рд░реНрдЧреЛрдВ рдХреА рдЦреЛрдЬ рдореЗрдВ рдХрдИ рдШрдВрдЯреЗ рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ 7x7 рдФрд░ рдЙрдЪреНрдЪ рдЖрдпрд╛рдореЛрдВ рдХреЗ рдЬрд╛рджреБрдИ рд╡рд░реНрдЧреЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рди рдЕрднреА рднреА рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдмрд╛рдХреА рд╣реИредрдЧрдгрд┐рддреАрдп рдФрд░ рдПрд▓реНрдЧреЛрд░рд┐рджрдорд┐рдХ рд░реВрдк рд╕реЗ, рдХрдИ рдЕрдирд╕реБрд▓рдЭреЗ рдореБрджреНрджреЗ рднреА рд╣реИрдВ:- ┬л ┬╗ N. 22 , 33 8 ( 1, ), 44 , 7040, . .
- , .
- . , NVIDIA Tesla , - , . , . , ;)
рдЬрд╛рджреВ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рдЧреБрдгреЛрдВ рдкрд░ рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрдЧрд░ рд░реБрдЪрд┐ рд╣реЛредрдкреБрдирд╢реНрдЪ: рдЙрд╕ рдкреНрд░рд╢реНрди рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, "рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдХреНрдпреЛрдВ рд╣реИред" рдмрд┐рдЬрд▓реА рдХреА рдЦрдкрдд рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЬрд╛рджреВ рд╡рд░реНрдЧреЛрдВ рдХреА рдЧрдгрдирд╛ рдмрд┐рдЯрдХреЙрдЗрди рдХреА рдЧрдгрдирд╛ рд╕реЗ рдмреЗрд╣рддрд░ рдпрд╛ рдмрджрддрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рдХреНрдпреЛрдВ рдирд╣реАрдВ? рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдорди рдХреЗ рд▓рд┐рдП рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдХрд╕рд░рдд рд╣реИ рдФрд░ рд▓рд╛рдЧреВ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдХрд╛рд░реНрдп рд╣реИред